TypeScript实现泛型接口时const可用let不可用的原因是什么?
TypeScript中const/let声明变量的类型校验差异原因
核心原因
这个问题本质是TypeScript针对const和let不同的语义规则,做的差异化静态类型校验导致的:
const声明的变量初始化后不可修改引用指向,TypeScript可以100%确定该变量后续永远指向你赋值的这个函数对象,不会被重新赋值为其他值。所以函数内部访问foo.id时,TS会默认foo的类型就是标注的Foo<number>,哪怕id属性是后续才赋值的,也能通过校验。let声明的变量支持中途修改引用指向,TypeScript会遵循暂时性死区的校验规则:在变量完成完整初始化之前,访问变量的类型会被判定为undefined。你在给let foo赋值函数的时候,函数内部引用了foo,此时TS认为foo还没有完成全部初始化(id属性还没赋值),也无法保证后续foo不会被重新赋值为其他值,自然就不认可foo.id的访问,抛出类型错误。
补充说明
你这段代码在纯JS环境下运行时,把const换成let是可以正常执行的,因为实际调用foo(2)的时机在foo.id = 100之后,运行时不会有问题,报错只来自TS的静态类型检查。
如果一定要用let写法,可以先给函数挂载完属性再赋值给变量,就能通过类型校验:
interface Foo<T> { (arg: T): void; id: T; } const func = function(x: number) { console.log(foo.id + x); } func.id = 100; let foo: Foo<number> = func; foo(2);
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

