我有两个interfaces
,其中一个扩展另一个。但是,我希望能够扩展第一个interface
并使其所有类型都可选。我不想在我的第二个interface
中重写第一个interface
的所有定义是可选的(因为在这一点上扩展的优势是什么?)或重新定义第一个interface
1}}因为它正在其他地方使用。
它看起来像什么:
interface First {
type1: string
type2: string
}
// Seemingly pointless rewrite (why would I even need to extend?)
interface Second extends First {
type1?: string
type2?: string
type3: string
type4: string
}
// What I imagine the extending should be (but doesn't work)
interface Second extends First? {
type3: string
type4: string
}
我做了我的研究并确实发现this question回答了一些非常相似的东西,但是这个问题已经触及了一年,我认为我的问题并不完全相同,因为我想制作整个扩展interface
可选,而不仅仅是其中的几种类型。
有没有办法在打字稿中做到这一点,或者我只是需要吮吸它并长一点interface
?
我正在编写一个React Web应用程序,并且有一个组件,它以允许用户编辑该实体的任何值的方式显示我的数据库中的实体。我希望我的React组件能够处理用户创建新实体的情况,以及用户正在编辑现有实体的情况。
为了与上面的示例保持一致,假设我的数据库实体的值由 First interface
复制,而React组件使用 Second中存在的两个传递的道具 interface
。 React组件将始终在第二中包含两个值,但不一定具有第一个的值。
在用户创建新实体的情况下,我想构建仅具有 Second 值的React组件,而不必为所有内容指定null
值的第一即可。在用户编辑现有实体的情况下,我会传递第一个和第二个中的所有内容。
在这两种情况下,它都是相同的UI,但是使用不同的值集构建。
答案 0 :(得分:12)
您可以在type aliases类型上使用intersection和Partial:
type First = {
type1: string;
type2: string;
}
type Second = Partial<First> & {
type3: string;
type4: string;
}
答案 1 :(得分:8)
您可以使用Partial类型的接口执行此操作。
interface First {
type1: string;
type2: string;
}
interface Second extends Partial<First> {
type3: string;
type4: string;
}
答案 2 :(得分:1)
您还可以通过提供一个否则为空的界面来使所有零件成为可选零件:
export interface ISingleScope {
scope: string;
}
export interface IMultiScope {
scopes: string[];
check?: boolean;
}
export interface IProvidedScope
extends Partial<ISingleScope>, Partial<IMultiScope> {
}
但是,通常这将需要对所使用属性的显式测试,因为在运行时这些信息都不存在。因此,如果您的对象带有名称 options ,那就足够了:
if (options && options.scopes) {
// access properly 'IMultiScope'
}
答案 3 :(得分:0)
Extends
中的 interface
表示第二个对象将继承第一个对象所具有的内容,如果第一个对象的属性是可选的,则它们将在没有更改的情况下应用于第二个对象。您无法在Typescript中更改此行为。
对您提出的问题的答案不应该使用extends
来解决您的问题。