求大佬,这样的情况typescript如何定义对象?
已知有一个对象,key和value对应
{
a: { a1: 1 },
b: { b9: 1 },
c: { c5: 1 },
d: { d2: 1 },
...
}
怎么用ts来定义这样的数组?
[{
type: 'e',
value: { e1: 1 }
}, {
type: 'c',
value: { c5: 1 }
}]
回复
1个回答

test
2024-06-29
研究了一下,这个问题可以分为两个部分
- 如何约束转化函数的入参类型
利用 template type 很方便可以解决:
type Src<Ks extends string> = {
[K in Ks]: {
[P in `${K}${number}`]: number
}
}
const conv = <Ks extends string>(src: Src<Ks>) => {}
- 如何推导返回值类型:
我能想到的是 record 转 union 转 array,其中 UnionToArray
参考了网上的文章。
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
k: infer I
) => void
? I
: never
type UnionToOvlds<U> = UnionToIntersection<
U extends any ? (f: U) => void : never
>
type PopUnion<U> = UnionToOvlds<U> extends (a: infer A) => void ? A : never
type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true
type UnionToArray<T, A extends unknown[] = []> = IsUnion<T> extends true
? UnionToArray<Exclude<T, PopUnion<T>>, [PopUnion<T>, ...A]>
: [T, ...A]
type Src<Ks extends string> = {
[K in Ks]: {
[P in `${K}${number}`]: number
}
}
const conv = <Ks extends string, T extends Src<Ks>>(src: T) => {
const dist: { type: string, value: { [K: string]: number } }[] = []
for (const k in src) {
dist.push({ type: k, value: src[k] })
}
return dist as UnionToArray<{
[K in keyof T]: {
type: K
value: T[K]
}
}[keyof T]>
}
const dist = conv(src)
// ^?
// const dist: [{
// type: "a";
// value: {
// a1: number;
// };
// }, {
// type: "b";
// value: {
// b9: number;
// };
// }, {
// type: "c";
// value: {
// c5: number;
// };
// }, {
// type: "d";
// value: {
// d2: number;
// };
// }]
遗憾的是这两个思路不能共存于一个函数(在我看来),你可以按需求选择入参约束或返回类型。
回复

适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容