Typescript 在映射操作期间创建字符串文字联合类型时无法编译

Typescript 在映射操作期间创建字符串文字联合类型时无法编译,typescript,Typescript,当我们使用map时,字符串文字联合类型会失败,但当我们直接创建数组时则不会 这是一本书 错误: Type '{ measurements: { unit: string; }[]; }[]' is not assignable to type 'Thing[]'. Type '{ measurements: { unit: string; }[]; }' is not assignable to type 'Thing'. Types of property 'measurement

当我们使用
map
时,字符串文字联合类型会失败,但当我们直接创建数组时则不会

这是一本书

错误:

Type '{ measurements: { unit: string; }[]; }[]' is not assignable to type 'Thing[]'.
  Type '{ measurements: { unit: string; }[]; }' is not assignable to type 'Thing'.
    Types of property 'measurements' are incompatible.
      Type '{ unit: string; }[]' is not assignable to type 'Measurement[]'.
        Type '{ unit: string; }' is not assignable to type 'Measurement'.
          Types of property 'unit' are incompatible.
            Type 'string' is not assignable to type 'Unit'.
为什么在映射过程中会发生这种情况?我们如何预防它

一种方法是将测量转换为
。现在还不清楚为什么这是必要的,而且它比不使用cast更详细,所以我们宁愿不使用cast,除非这是唯一的方法

// works
const thingsToo: Thing[] = Array.from({ length: 5 }).map((i) => ({
    measurements: [{
        unit: 'g'
    } as Measurement]
}));

字符串文字类型的工作方式是字符串文字表达式 必须由字符串文字类型(或联合)上下文类型 包含字符串文字类型),以便将check类型设置为字符串 文本类型而不是字符串

在代码中,
'g'
字符串文字类型被扩展为
字符串
,因为在
数组…映射
表达式中没有上下文将其保留为文字

另一个解决方法是为
map
回调添加显式返回类型:

type Unit = 'g' | 'ml';

class Measurement { 
    unit: Unit;
}

class Thing { 
    measurements: Measurement[];
}

// works
const things: Thing[] = [{
    measurements: [{
        unit: 'g'
    }]
}];

// works
const thingsToo: Thing[] = Array.from({ length: 5 }).map((i): Thing => ({
    measurements: [{
        unit: 'g'
    }]
}));
type Unit = 'g' | 'ml';

class Measurement { 
    unit: Unit;
}

class Thing { 
    measurements: Measurement[];
}

// works
const things: Thing[] = [{
    measurements: [{
        unit: 'g'
    }]
}];

// works
const thingsToo: Thing[] = Array.from({ length: 5 }).map((i): Thing => ({
    measurements: [{
        unit: 'g'
    }]
}));