TypeScript 如何理解这个条件?

huangapple go评论66阅读模式
英文:

How can TypeScript understand this condition?

问题

当将类型为unknown的变量分配给另一个变量时,我们应该经过unknown变量的类型检查,但TypeScript如何理解这种特定情况呢?看起来它返回一个boolean,但我认为它更复杂:

let first: unknown = 5;
let second: number;

const result = typeof first === 'number';

if(result){
    second = first; // 错误:类型'unknown'不能赋值给类型'number'
}

if(typeof first === 'number'){
    second = first; // 没有错误
}

如果您有任何其他翻译需求,请告诉我。

英文:

when assigning a variable of type unknown to another variable, we should go through the type checking of the unknown variable but how can TypeScript understand this specific condition? looks like it's returning a boolean but I think it's more complicated :

let first: unknown = 5;
let second: number;

const result = typeof first === 'number';

if(result){
    second = first; // error : Type 'unknown' is not assignable to type 'number'
}

if(typeof first === 'number'){
    second = first; // no errors
}

答案1

得分: 5

TypeScript在2021年6月的PR#44730之后,增加了对间接表达式类型缩小的支持。在介绍此功能的说明中,Anders Hejsberg提到了此功能的限制(重点和格式由我添加):

> 只有在以下情况下,通过_间接引用_进行缩小才会发生:
> * _条件表达式_或_鉴别属性_访问是在没有类型注释的const变量声明中声明的,并且...
> * 被缩小的引用是以下之一:
> * const变量
> * readonly属性
> * 函数体中没有赋值的参数。

在您的案例中,您的let first: unknown = 5;变量的赋值不能使用这个功能,因为它是一个let局部变量,而不是一个const局部变量。

因此,如果您将代码更改为使用const first而不是let first,那么它就能正常工作:


const first: unknown = 5;
let second: number;

const result = ( typeof first === 'number' );

if( result ) {
    second = first; // OK!
}

if( typeof first === 'number' ) {
    second = first; // OK!
}

TypeScript playground链接

英文:

TypeScript added support for indirect expression type narrowing in TypeScript 4.4 after PR #44730 was added in June 2021. In the notes introducing this feature, Anders Hejsberg mentions the limitations of this feature (emphasis and formatting mine):

> Narrowing through indirect-references occurs only when:
> * the conditional-expression or discriminant-property access is declared in a const variable declaration with no type annotation, and...
> * the reference being narrowed is one-of:
> * a const variable or
> * a readonly property or
> * a parameter for which there are no assignments in the function body.

In your case your let first: unknown = 5; variable's assign cannot be used with this feature because it's a let local variable instead of a const local.

So if you change the code to use const first instead of let first, then it works:


const first: unknown = 5;
let second: number;

const result = ( typeof first === 'number' );

if( result ) {
    second = first; // OK!
}

if( typeof first === 'number' ) {
    second = first; // OK!
}

TypeScript playground link

huangapple
  • 本文由 发表于 2023年2月6日 05:32:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/75355670.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定