当我们使用 map
时,字符串文字联合类型会失败,但当我们直接创建数组时不会。
这是一个Fiddle from the Playground .
type Unit = 'g' | 'ml';
class Measurement {
unit: Unit;
}
class Thing {
measurements: Measurement[];
}
// works
const things: Thing[] = [{
measurements: [{
unit: 'g'
}]
}];
// fails
const thingsToo: Thing[] = Array.from({ length: 5 }).map((i) => ({
measurements: [{
unit: 'g'
}]
}));
错误:
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'.
为什么在 map
期间会发生这种情况?我们该如何预防?
一种方法是转换为Measurement
。目前还不清楚为什么这是必要的,而且它也比不转换更冗长,所以我们宁愿不使用转换,除非那是唯一的方法。
// works
const thingsToo: Thing[] = Array.from({ length: 5 }).map((i) => ({
measurements: [{
unit: 'g'
} as Measurement]
}));
最佳答案
The way string literal types work is that a string literal expression must be contextually typed by a string literal type (or a union containing a string literal type) in order to type check as a string literal type instead of as string.
在您的代码中,'g'
字符串文字类型被扩展为 string
,因为没有上下文可以将其保留为 Array 中的文字...映射
表达式。
另一种解决方法是为 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'
}]
}));
关于typescript - 在映射操作期间创建时,字符串文字联合类型无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52617679/