TypeScript:将包含字符串联合的对象类型映射到返回结果中
这是这个问题的延伸: 这个问题扩展了最后一个问题,将文本元组嵌入到对象上的任意键中,并将它们映射到输出键上TypeScript:将包含字符串联合的对象类型映射到返回结果中,typescript,generics,Typescript,Generics,这是这个问题的延伸: 这个问题扩展了最后一个问题,将文本元组嵌入到对象上的任意键中,并将它们映射到输出键上 function myfn<T extends string>(opts: { [key: string]: T[] }) { const out: ??? = {}; for (const [key,val] of Object.entries(opts)) { out[key] = val[0]; } return out; } const res
function myfn<T extends string>(opts: { [key: string]: T[] }) {
const out: ??? = {};
for (const [key,val] of Object.entries(opts)) {
out[key] = val[0];
}
return out;
}
const result = myfn({
foo: ['a', 'b', 'c'],
bar: ['x', 'y', 'z'],
})
// Expected: {
// foo: 'a' | 'b' | 'c',
// bar: 'x' | 'y' | 'z',
// }
函数myfn(选项:{[key:string]:T[]}){
常数out:?={};
for(对象项(opts)的常量[key,val]{
out[key]=val[0];
}
返回;
}
常量结果=myfn({
foo:[a',b',c'],
条形图:['x','y','z'],
})
//预期:{
//foo:‘a’|‘b’|‘c’,
//酒吧:“x”|“y”|“z”,
// }
要获得预期的类型,需要在myfn
中/上输入哪些类型
我知道这和你有关系,但我不知道它到底应该是什么。现在没有完整的答案,但这正是你要找的类型:
type MapToUnion<T extends { [key: string]: readonly string[] }> =
{
-readonly [K in keyof T]: T[K][number]
}
const opts = {
foo: ['a', 'b', 'c'],
bar: ['x', 'y', 'z'],
} as const;
type Mapped = MapToUnion<typeof opts>;
// type Mapped = {
// foo: "a" | "b" | "c";
// bar: "x" | "y" | "z";
// }
类型MapToUnion=
{
-只读[K in keyof T]:T[K][number]
}
常量选项={
foo:[a',b',c'],
条形图:['x','y','z'],
}作为常量;
类型Mapped=MapToUnion;
//类型映射={
//foo:“a”|“b”|“c”;
//酒吧:“x”|“y”|“z”;
// }
用户系统故障
在自由节点上
在##typescript
中编写了此解决方案:
type MyFnResult<T extends string, Options extends {readonly [k:string]: T[]}> = Options extends any? { [K in keyof Options]: Options[K][number] } : never
function myfn<
T extends string,
Options extends {readonly [k:string]: T[] }
>(opts: Options): MyFnResult<T, Options> {
const out: Record<string, string> = {};
for (const [key,val] of Object.entries(opts)) {
out[key] = val[0];
}
return out as any
}
const result = myfn({
foo: ['a', 'b', 'c'],
bar: ['x', 'y', 'z'],
})
// Out type: {
// foo: 'a' | 'b' | 'c',
// bar: 'x' | 'y' | 'z',
// }
键入MyFnResult=Options是否扩展了任何?{[K in keyof Options]:选项[K][number]}:从不
函数myfn<
T扩展字符串,
选项扩展了{readonly[k:string]:T[]}
>(选项:选项):MyFnResult{
const out:Record={};
for(对象项(opts)的常量[key,val]{
out[key]=val[0];
}
照常返回
}
常量结果=myfn({
foo:[a',b',c'],
条形图:['x','y','z'],
})
//输出类型:{
//foo:‘a’|‘b’|‘c’,
//酒吧:“x”|“y”|“z”,
// }
它起作用了。我一点也不懂。但是它是有效的。有没有办法不用作为常量来做这件事呢?@Steven不是回答者,如果你不做常量
断言,让编译器推断选项的类型
,它会选择不合理的{foo:string[],bar:string[]}
,它完全忘记了任何可能的字符串文字<代码>常量
断言是告诉编译器记住这些字符串文字的最简单的方法。这是可以做到的,请看——我在这里尝试的是将其与类型映射结合起来,仅此而已。这与我的答案相同,我只是不想像任何
那样对完整答案进行转换。类型myfnsult
和MapToUnion
在功能上是相同的。His没有使用作为常量,我认为这是主要的区别,但却是一个重要的区别。