我想在打字稿中创建一个类型或接口,它采用 optional 泛型参数。为了使其可选,我使用默认的通用参数语法:
interface IdData {
id: string;
}
interface WizardContext<T = undefined> {
step: number;
items: T extends IdData ? T[] : undefined
}
这里的概念是,如果从
WizardContext
构建了一个更具体的类型,并且类型参数T
满足条件T extends IdData
,那么这个具体类型应该有一个属性items
,即T[]
。我正在努力实现的一些例子:
// ------- Defining some extended types -------------:
interface User extends IdData {
name: string;
}
type UserWizardContext = WizardContext<User>;
// ------- Trying to satisfy those types: ------------
// Works
const userWizardProps: UserWizardContext = {
step: 2,
items: [{ name: 'name1', id: 'id1' }]
}
// Errors as expected, as `items` is missing
const userWizardProps2: UserWizardContext = {
step: 2,
}
// Errors, even though items should be allowed to be undefined
const simpleWizardProps: WizardContext = {
step: 2
}
// I have to declare items as undefined, when it should be able to just be omitted
const simpleWizardProps2: WizardContext = {
step: 2,
items: undefined
}
在最后一种情况下,即使
simpleWizardProps2
使用没有类型参数定义的WizardContext
,如果我不手动包含items: undefined
它仍然会出错。这本质上是可选参数与未定义参数之间的区别。我不希望 items
是可选的,因为然后在其他不同的地方定义它,我得到 Object is possibly 'undefined'
问题。
我也尝试过使用类型而不是接口来做到这一点:
type WizardContextType<T = undefined> = {
step: number;
} & (T extends IdData ? { items: T[]} : {})
但这最终没有什么区别。如果传递给
WizardContext
或 WizardContextType
的类型参数没有扩展 IdData
,items
仍然期望被声明为 undefined
,而目标是实际省略它。
如何根据类型参数是否满足条件来创建这个可选属性?
在这种情况下,如果 T 没有扩展 IdData,那么 itens 属性的类型是未定义的,但仍然是必需的。 创建一个你应该使用的可选属性
interface WizardContext<T = undefined> {
step: number;
items?: T extends IdData ? T[] : undefined
}