我已经有类似的问题:根据另一个字段的值声明一个字段的类型
主要区别是现在我不知道可能值的列表
所以假设我有这些接口:
interface One {
children: Child[]
}
interface Child<T = any> {
props: T,
component: (props: T) => null
}
const ComponentOne = (props: string) => null;
const ComponentTwo = (props: number) => null;
const one: One = {
children: [
{
props: 5,
component: ComponentOne
},
{
props: 'string',
component: ComponentTwo
}
]
}
我需要
props
与 component
的道具具有完全相同的类型。
上面的代码不会因为
any
而给出任何错误,但如果我删除它,interface One
将会中断,因为它需要Child
的类型,但它们不能都相同
这可能是一个非常明显的问题,但我不知道如何解决它
附注我没有任何理由地写了
interface
,如果可以使用type
修复那么对我来说是可以接受的
你应该付出一些努力来建立自己的类型。例如,您可以使用:
interface One<T> {
children: (T extends any ? Child<T> : never)[]
}
将
props
类型分配给不同的子对象(您可以删除 Simplify 实用程序和内联 ONE
,这是为了调试和演示而完成的):
type Simplify<T> = {[K in keyof T]: T[K] extends Function ? T[K] extends (...args: infer B) => infer A ? (...args: B) => Simplify<A> : never : Simplify<T[K]>} extends infer A ? A : never;
const ComponentOne = (props: string) => null;
const ComponentTwo = (props: number) => null;
const Components = [ComponentOne, ComponentTwo];
{
interface One<T> {
children: (T extends any ? Child<T> : never)[]
}
interface Child<T> {
props: T,
component: (props: T) => null
}
type ONE = Simplify<One<Parameters<typeof Components[number]>[0]>>;
const one: ONE = {
children: [
{
props: '',
component: ComponentOne
},
{
props: 1,
component: ComponentTwo
}
]
}
}
// ==================== alternative ===================
{
interface Child<C extends (props: any) => null> {
props: Parameters<C>[0],
component: C
}
interface One<C extends (props: any) => null> {
children: (C extends any ? Child<C> : never)[]
}
type ONE = Simplify<One<typeof Components[number]>>;
const one: ONE = {
children: [
{
props: '',
component: ComponentOne
},
{
props: 1,
component: ComponentTwo
}
]
}
}