【发布时间】:2023-01-25 13:00:56
【问题描述】:
我正在尝试重构我的代码以抽象冗余部分以提高可维护性。我正在尝试创建一个函数,该函数将根据传递的参数执行不同的较小函数并返回必要的数据。
对于这些较小的函数,它们返回一个对象,该对象的属性来自工厂函数,加上我定义的任何其他属性,这些属性可能存在于所有较小的函数之间,也可能不存在。
const factoryFunc = () => ({
func1: () => 'func1',
func2: () => 'func2',
func3: () => 'func3',
})
const extendedFuncs1 = () => ({
...factoryFunc(),
additionalFunc1: () => 'additionalFunc1'
})
const extendedFuncs2 = () => ({
...factoryFunc()
})
我使用 ReturnType 实用程序提取了从这些函数返回的类型。我想获取每个可用函数的键,因此我创建了一个类型,将键映射到它们各自的函数名称。
type TExtendedFuncs1 = ReturnType<typeof extendedFuncs1>
type TExtendedFuncs2 = ReturnType<typeof extendedFuncs2>
type TFuncsTypes = {
extendedFuncs1: keyof TExtendedFuncs1;
extendedFuncs2: keyof TExtendedFuncs2;
}
然后,我创建了一个条件类型来检查该属性是否属于某个函数,如果是,则提供该函数可用的键。 OtherType 仅供参考。
type TOtherTypes = {
otherType1: string;
otherType2: number
}
type Conditional<T = keyof (TOtherTypes & TFuncsTypes)> = T extends keyof TFuncsTypes ? {
name: T;
objKey: TFuncsTypes[T]
} : never
有了这个,我希望 objKey 属性成为 TFuncsTypes['extendedFuncs1'] 或 TFuncsTypes['extendedFuncs2'] 返回对象的键。此外,如果它是TFuncsTypes['extendedFuncs1'],则additionalFunc1 属性应该存在。
const testFunc = (data: Conditional[]) => {
const findData = (key: string) => data.find((d) => d.name === key);
const res1 = extendedFuncs1()[findData('extendedFuncs1')!.objKey]
const res2 = extendedFuncs2()[findData('extendedFuncs2')!.objKey]
return {res1, res2}
}
但是,打字稿给我一个res2的错误
Property 'additionalFunc1' does not exist on type '{ func1: () => string; func2: () => string; func3: () => string; }'
我知道它不存在,因为它是在工厂外定义的附加属性,但为什么它没有根据 TFuncsTypes['extendedFuncs2'] 中定义的键进行评估?
这是我制作的playground。
【问题讨论】:
-
是的@jcalz,这解决了这个问题。非常感谢您的分享。
-
还有一件事,如果我在另一个函数中使用
findData函数怎么办?我是否也必须使该功能通用? -
或许?这取决于具体情况,并且可能超出此问题及其评论部分的范围。
标签: javascript typescript