Typescript 中如何编写含复杂返回值的函数类型声明?
实现了一个函数可实现对象扁平化,数据转换示例(传入 => 传出):
{ margin: { left: '20px', right: '30px' } } => { 'margin-left': '20px', 'margin-right': '30px' }
{ color: { button: { warning: 'yellow' } } } => { 'color-button-warning': 'yellow' }
请问如何编写函数的类型声明呢?以便于vscode里面提示扁平化后自动生成的键名,对开发者友好,比如 color-button-warning 和 margin-left。
补充一下传入的结构化数据的类型声明:declare const a = {margin: {left: string}}
类似这样,是自动生成的。
回复
1个回答

test
2024-07-17
做个类型体操就行,大致写了下,
type JoinKey<P extends string, K extends string>
= P extends '' ? K : `${P}-${K}`
type Inner<T, P extends string = ''> =
{
[K in keyof T]:
T[K] extends object
? Inner<T[K], JoinKey<P, K & string>>
: [JoinKey<P, K & string>, T[K]]
}[keyof T]
type _Flat<T>
= T extends [string, string | number | boolean]
? {
[K in T[0]]: T[1]
}
: T extends [string, object]
? _Flat<T[1]>
: never
type UnionToIntersection<T> =
(T extends any ? (x: T) => any : never) extends
(x: infer R) => any ? R : never
type FlatObject<T> = UnionToIntersection<_Flat<Inner<T>>>
declare function flatObj<T>(obj: T): FlatObject<T>
const res = flatObj({
margin: {
left: '10px',
right: '8px',
},
padding: {
top: '4px'
},
color: {
button: {
success: 'green',
failure: {
active: 'red',
hover: 'pink'
}
}
}
})
PS: 应该是有更好的写法,不过暂时也没想好。另外有个问题这里没有推断出对应的值出来
回复

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