typescript中类型断言的详细逻辑是什么?

typescript中类型断言的详细逻辑是什么?,typescript,type-assertion,Typescript,Type Assertion,我将类型断言视为类似于Hi编译器的东西,我比您更了解这个变量的类型。跟我来 但编译器似乎仍然有自己的逻辑来推断类型。比如说假设, interface PM_MGEInfo { category: string; bid: string; cid?: string; labs?: { [key: string]: any }; } 然后,1和2没有问题,但是3抛出一个TS2352错误 函数makeMgeInfo(bid:string):PM\u MGEInfo{

我将
类型断言
视为类似于
Hi编译器的东西,我比您更了解这个变量的类型。跟我来

但编译器似乎仍然有自己的逻辑来推断类型。比如说假设,

interface PM_MGEInfo {
    category: string;
    bid: string;
    cid?: string;
    labs?: { [key: string]: any };
}
然后,1和2没有问题,但是3抛出一个TS2352错误

  • 函数makeMgeInfo(bid:string):PM\u MGEInfo{
    返回{
    投标
    };
    }
    
  • 函数makeMgeInfo(bid:string):PM\u MGEInfo{
    返回{
    投标,
    实验室:{}
    };
    }
    
  • 函数makeMgeInfo(bid:string):PM\u MGEInfo{
    返回{
    投标,
    //错误TS2352:无法将类型“{labs:{poi_id:string;};bid:string;}”转换为类型“PM_MGEInfo”。
    //类型“{labs:{poi_id:string;};bid:string;}”中缺少属性“category”。
    实验室:{a:1}
    };
    }
    
  • 为什么
    类型断言
    开始检查3中的其他字段?有人知道它的详细逻辑吗



    更新:我在Github中创建了一个问题。

    我看到两个选项。使用
    部分
    任何
    。当使用any时,您有责任确保一切正常,所以请将其作为最后一个选项使用

    这两方面的例子:

    function makeMgeInfoWithPartial(bid: string): Partial<PM_MGEInfo> {
      // props are optional but only those defined by PM_MGEInfo are valid
      return {
        bid,
        labs: {a: 1}
      }
    }
    
    function makeMgeInfoWithAny(bid: string): PM_MGEInfo {
      return {
        bid,
        labs: {a: 1},
        whatever: 'also works'
      } as any
    }
    
    函数makeMgeInfoWithPartial(bid:string):Partial{
    //道具是可选的,但只有PM_MGEInfo定义的道具才有效
    返回{
    投标,
    实验室:{a:1}
    }
    }
    函数makeMgeInfoWithAny(bid:string):PM\u MGEInfo{
    返回{
    投标,
    实验室:{a:1},
    不管怎样:“也有效”
    }一样
    }
    
    我认为编译器不会将您的值
    {a:1}
    识别为类型
    {[key:string]:any}
    ,因为如果您像这样更改行,则不会出现编译器错误:

    function makeMgeInfo(bid: string): PM_MGEInfo {
      return <PM_MGEInfo>{
        bid,
        labs: {a: 1} as {[key: string]: any}
      };
    }
    
    并在函数中调用它:

    makeMgeInfo(bid: string): PM_MGEInfo {
      return <PM_MGEInfo>{
        bid,
        labs: this.mylabs
      };
    }
    
    makeMgeInfo(出价:字符串):PM\u MGEInfo{
    返回{
    投标,
    实验室:这是我的
    };
    }
    
    因此,我想说,编译器无法从labs字段识别您定义的类型。本例中的错误消息具有误导性。

    检查规范,其灵感来自:

    在形式为e的类型断言表达式中,e由T上下文类型化(第4.23节),生成的e类型必须可分配给T,或者T必须可分配给生成的e类型的扩展形式,否则会发生编译时错误

    对于情况1,
    T
    显然可分配给
    e

    对于案例2,
    e
    的扩展形式是
    {bid:string,labs:Object}
    ,T可分配给它。请注意,
    labs?
    可分配给
    对象
    (事实上,我不确定,但这是我唯一可能的解释)


    对于案例3,上述两个条件都不满足。

    听起来像是回归。是的,对我来说似乎是个bug。如果您声明一个
    PM_MGEInfo
    变量,并将
    {bid:'o'}
    赋值给它,则会显示一个错误,表示缺少
    类别。这应该是1)和2)中的行为。不知道为什么只在案例3中触发)。似乎
    {[key:string]:any}
    索引签名触发了错误。我建议提出一个问题。我同意你的观点,这些选项会使它起作用,但问题是为什么它会起作用。。添加额外的
    labs
    属性不应触发该错误。@TitianCernicova Dragomir TS2352错误不是由
    labs
    引起的。错误消息显示类型中缺少属性“类别”
    。如果没有
    类别
    ,则该类型不完整。
    类别
    在此中以及
    返回{bid}
    中缺失,并且只有在添加
    实验室
    时才有效。。感谢您澄清@TitianCernicova Dragomir。我之前没看到。隐马尔可夫模型。。不知道为什么!希望其他人可以。:-)
    function makeMgeInfoWithPartial(bid: string): Partial<PM_MGEInfo> {
      // props are optional but only those defined by PM_MGEInfo are valid
      return {
        bid,
        labs: {a: 1}
      }
    }
    
    function makeMgeInfoWithAny(bid: string): PM_MGEInfo {
      return {
        bid,
        labs: {a: 1},
        whatever: 'also works'
      } as any
    }
    
    function makeMgeInfo(bid: string): PM_MGEInfo {
      return <PM_MGEInfo>{
        bid,
        labs: {a: 1} as {[key: string]: any}
      };
    }
    
    mylabs: {[key: string]: any} = {a: 1};
    
    makeMgeInfo(bid: string): PM_MGEInfo {
      return <PM_MGEInfo>{
        bid,
        labs: this.mylabs
      };
    }