接口上的可选参数基于打字稿中的类型参数

问题描述 投票:0回答:1

我想在打字稿中创建一个类型或接口,它采用 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
,而目标是实际省略它。

TS playground 展示了这个问题

如何根据类型参数是否满足条件来创建这个可选属性?

typescript generics typescript-generics optional-parameters generic-type-argument
1个回答
0
投票

在这种情况下,如果 T 没有扩展 IdData,那么 itens 属性的类型是未定义的,但仍然是必需的。 创建一个你应该使用的可选属性

interface WizardContext<T = undefined> {
  step: number;
  items?: T extends IdData ? T[] : undefined
}
© www.soinside.com 2019 - 2024. All rights reserved.