类型推断 - 为什么在使用隐式 Any 时 TypeScript 没有显示错误?
在我的 tsconfig.json 中,我设置了 "noImplicitAny": true。然而,下面的代码并没有产生错误:
let x;
x = 5;
x = "a";
x = null;
console.log(x);
这里 x 难道不是隐式地被设置为 any 吗(与显式不同,显式的话我会写 let x: Any;)?
我明白,由于不同的赋值,编译器在这里可以在编译时推断出Any,但我以为选项"noImplicitAny": true是用来防止这种推断的。
在这种情况下,有其他编译器选项可以显示错误吗?
答案#1
根据上下文,TypeScript 可能会将一个变量推断为其实际类型的子类型:
let a: number | number[] = 0;
if (!Array.isArray(a)) a = [a];
void a;
// ^?
// let a: number[] | (number & any[])
a = 123;
void a;
// ^?
// let a: number
if (a === 999) {
void a;
// ^?
// let a: 999
}
function f() {
// doesn't work in functions:
void a;
// ^?
// let a: number | number[]
}
如果你将变量类型定义为unknown,子类型化在赋值时将停止工作。
如果你将变量类型定义为any,子类型化将停止在所有地方工作。
如果你不写类型,它将从你赋值的值中获取。
然而,如果你完全不定义变量类型,它将是一个可子类型化的any
答案#2
当你的代码中有一个未分配的 let 变量时,Typescript 会进行后处理,并且它会将最后一次赋值的类型作为你的变量类型(别问我为什么)
这就是为什么我们通常使用 'const' 关键字而不是 'let'。
let x; // here its any
x = 5; // here its number
const num = x; // hover on num to see its type
x = "a"; // here its string
const str = x; // hover on str to see its type
str = 123; // that's not allowed
x = 123; // but this is
console.log(x); // here its number again
