打字稿中类型断言的详细逻辑是什么?

What is the detail logic of type assertion in typescript?

我将 type assertion 视为 Hi Compiler, I know the type of this variable better than you. Just follow me!

不过好像编译器还是有自己的推断类型的逻辑。例如,假设,

interface PM_MGEInfo {
    category: string;
    bid: string;
    cid?: string;
    labs?: { [key: string]: any };
}

那么1&2没问题,3就报TS2352错误

  1. function makeMgeInfo(bid: string): PM_MGEInfo {
        return <PM_MGEInfo>{
            bid
        };
    }
    
  2. function makeMgeInfo(bid: string): PM_MGEInfo {
        return <PM_MGEInfo>{
            bid,
            labs: {}
        };
    }
    
  3. function makeMgeInfo(bid: string): PM_MGEInfo {
        return <PM_MGEInfo>{
            bid,
            // error TS2352: Type '{ labs: { poi_id: string; }; bid: string; }' cannot be converted to type 'PM_MGEInfo'.
            // Property 'category' is missing in type '{ labs: { poi_id: string; }; bid: string; }'.
            labs: {a: 1}
        };
    }
    

为什么type assertion开始检查3中的其他字段?有人知道它的详细逻辑吗?


更新:我在 Github Microsoft/TypeScript#23698 中创建了一个问题。

我看到两个选项。使用 Partial<T>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
}

我认为编译器无法将您的值 {a: 1} 识别为 { [key: string]: 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
  };
}

因此我想说,编译器无法识别您在实验室字段中定义的类型。这种情况下的错误消息非常具有误导性。

检查规范 4.16 Type Assertions, which is inspired by :

In a type assertion expression of the form < T > e, e is contextually typed (section 4.23) by T and the resulting type of e is required to be assignable to T, or T is required to be assignable to the widened form of the resulting type of e, or otherwise a compile-time error occurs.

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

对于情况 2,e 的扩展形式是 {bid: string, labs: Object},T 可分配给它。注意labs?是可以赋值给Object的(其实我也不确定,但这是我唯一可能的解释)。

情况3,以上条件都不满足