Typescript 可以使用字符串文字类型和类型“;“字符串”;是否混合并用作映射类型中的键?
我想定义一个映射类型,其中键Typescript 可以使用字符串文字类型和类型“;“字符串”;是否混合并用作映射类型中的键?,typescript,types,Typescript,Types,我想定义一个映射类型,其中键'foo'和'bar'的类型为number,所有其他键的类型为string 我的第一个直觉是用这样的条件类型来解决这个问题: type FooOrBar = 'foo' | 'bar'; type MyMappedType = { [key in FooOrBar | string]: key extends FooOrBar ? number : string; } var x: MyMappedType = { foo: 1,
'foo'
和'bar'
的类型为number
,所有其他键的类型为string
我的第一个直觉是用这样的条件类型来解决这个问题:
type FooOrBar = 'foo' | 'bar';
type MyMappedType = {
[key in FooOrBar | string]: key extends FooOrBar ? number : string;
}
var x: MyMappedType = {
foo: 1, // Type 'number' is not assignable to type 'string'.(2322)
bar: 2, // Type 'number' is not assignable to type 'string'.(2322)
baz: 'I am a string' // ok!
}
这里的问题是,typescript将typealiasFooOrBar | string
缩小到键中的typestring
。所以事实上typescript将该类型计算为
type MyMappedType = {
[key in string]: key extends FooOrBar ? number : string;
}
因此,条件键extends FooOrBar
总是false,类型定义对我的需要是无用的
我的第二个直觉是使用交叉点类型:
type FooOrBar = 'foo' | 'bar';
type MyMappedType = {
[key in FooOrBar]:number;
} & {
[key in string]: string;
};
var x: MyMappedType = { // Type 'number' is not assignable to type 'string'.(2322)
foo: 1,
bar: 2,
baz: 'I am a string'
}
但这也不行
有没有可能在typescript中定义这样的类型?您可以为每个索引案例创建属性,例如
type numberLiterals = 'foo' | 'bar'
type myMappedType = {
numbers: { [key in numberLiterals]: number; };
strings: { [key: string]: string };
}
var x: myMappedType = {
numbers: {
foo: 1,
bar: 2,
// zzz: 5 -> not assignable
},
strings: {
fo: '',
fooo: ''
// baar: 1 -> not assignable
}
}
是的,这会奏效,但这与其说是解决方案,不如说是一种变通办法。我宁愿为我的代码结构定义类型,也不愿将我的代码结构调整为类型。@Simon我认为不可能对字符串执行此操作,因为
[key:string]
已经允许任何字符串(包括联合类型中的字符串)。不过你可以用数字。@Simon事实上,经过一些挖掘,你可以将交叉点改为一个并集,它应该可以按照你的意图工作。出于上述原因,Union仍然不喜欢它。Union将允许初始分配,但您将无法访问“字符串索引”道具(x['baz']
)@AlekseyL。啊,你说得对,FooOrBar
属性在访问它们时也会变成一个string | number
。我想当时我的第一个直觉是对的