Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 不同范围变量的类型推断_Typescript_Tsc - Fatal编程技术网

Typescript 不同范围变量的类型推断

Typescript 不同范围变量的类型推断,typescript,tsc,Typescript,Tsc,考虑以下代码(在TypeScript 3.2.2中运行): 由于test的返回类型及其签名不匹配,因此无法编译: error TS2322: Type '"successful"' is not assignable to type 'IResult<"hello">'. 生成预期的返回类型“成功”|“失败” 使用让: function test(): typeof status { let status = 'hello'; // notice the let here

考虑以下代码(在TypeScript 3.2.2中运行):

由于
test
的返回类型及其签名不匹配,因此无法编译:

error TS2322: Type '"successful"' is not assignable to type 'IResult<"hello">'.
生成预期的返回类型
“成功”|“失败”

使用

function test(): typeof status {
  let status = 'hello'; // notice the let here

  return 'successful';
} 
这会编译,但返回类型为
string
,内部定义将再次使用

我希望
tsc
使用
status
,在这两种情况下,无论
test
中存在什么声明,它都是在作用域中定义的最高级别来评估其返回类型为什么出现上述行为?这应该与
tsc
如何决定使用哪些变量进行类型推断有关。

这里有12种情况:
(常量、let、var)*(全局、局部)*(显式字符串并集、推断字符串)

TL;博士

简单方法:
  • 如果显式地在外部范围中指定类型,则结果总是相同的:union of
    “ok”|“no”
明白了:
  • 由于内部
    let
    const
    可用于返回位置的
    typeof
    ,因此它们对外部声明进行阴影处理
  • 内部
    var
    对于返回类型位置的
    typeof
    不可用(无论出于何种原因)
增加额外的混乱:
  • 如果你想推断:<代码>让和<代码> var >代码>将考虑类型为“代码>字符串”,并且<代码> const 将键入精确的[不变的原始]值。

供参考的个案清单:
你的问题是什么?谢谢你完整的回答-很容易理解。我用组合框更新了答案,当内部出现阴影时。
function test(): typeof status {
  var status = 'hello'; // notice the var here

  return 'successful';
}
function test(): typeof status {
  let status = 'hello'; // notice the let here

  return 'successful';
} 
// Infer, Inner
function test_inner_let(): typeof status01 { // type is string
  let status01 = 'ok'; // let is mutable, so type is only string
  return 'lol';
}
function test_inner_const(): typeof status02 { // type is 'ok'
  const status02 = 'ok'; // const allows to specify type to exact 'ok'
  return 'lol'; // error, 'lol' is not assignable to 'ok'
}
function test_inner_var(): typeof status03 { // type is any, TS warning: status03 not found
  var status03 = 'ok'; // var is mutable, so type is string
  return 'lol';
}

// Explicit, Inner
function test_inner_let_t(): typeof status11 { // type is union 'ok'|'no'
  let status11: 'ok' | 'no' = 'ok';
  return 'lol'; // error, 'lol' is not assignable to 'ok'|'no'
}
function test_inner_const_t(): typeof status12 { // type is union 'ok'|'no'
  const status12: 'ok' | 'no' = 'ok';
  return 'lol'; // error, 'lol' is not assignable to 'ok'|'no'
}
function test_inner_var_t(): typeof status13 { // type is any, TS warning: status13 not found
  var status13: 'ok' | 'no' = 'ok';
  return 'lol';
}

// Explicit, Outer - everything works the same
let status21: 'ok' | 'no' = 'ok';
function test_outer_let_t(): typeof status21 { // type is union 'ok'|'no'
  return 'lol'; // error, 'lol' is not assignable to 'ok'|'no'
}
const status22: 'ok' | 'no' = 'ok';
function test_outer_const_t(): typeof status22 { // type is union 'ok'|'no'
  return 'lol'; // error, 'lol' is not assignable to 'ok'|'no'
}
var status23: 'ok' | 'no' = 'ok';
function test_outer_var_t(): typeof status23 { // type is union 'ok'|'no'
  return 'lol'; // error, 'lol' is not assignable to 'ok'|'no'
}

// Infer, Outer
let status31 = 'ok'; // type is string
function test_outer_let(): typeof status31 { // type is string
  return 'lol';
}
const status32 = 'ok'; // const allows to specify type to exact 'ok'
function test_outer_const(): typeof status32 { // type is 'ok'
  return 'lol'; // error, 'lol' is not assignable to 'ok'
}
var status33 = 'ok'; // var is mutable, so type is string
function test_outer_var(): typeof status33 { // type is string
  return 'lol';
}

// (Explicit, Outer const) + (Implicit, Inner)
const status41: 'ok' | 'no' = 'ok';
function test_combo_let(): typeof status41 { // type is string, inner let took preference
  let status41 = 'ok';
  return 'lol';
}
const status42: 'ok' | 'no' = 'ok';
function test_combo_const(): typeof status42 { // type is 'sorry', inner const took preference
  const status42 = 'sorry';
  return 'lol'; // error, 'lol' is not assignable to 'sorry'
}
const status43: 'ok' | 'no' = 'ok';
function test_combo_var(): typeof status43 { // type is union 'ok'|'no', var is not bubling up
  var status = 'whatever';
  return 'lol'; // error, 'lol' is not assignable to 'ok'|'no'
}