Typescript 数组中的对象,其类型扩展自相同的接口

huangapple go评论65阅读模式
英文:

Typescript array of objects that has a type extending from the same interface

问题

我有一个可以存储扩展ISlide的对象的数组。

interface ISlide {
    component: ComponentType;
}

interface ITitleSlide extends ISlide {
    title: string;
    subtitle: string;
}

interface IHeaderSlide extends ISlide {
    header: string;
}

const slides: (ITitleSlide | IHeaderSlide)[] = [
    {
        component: TitleSlide,
        title: 'Title',
        subtitle: 'Subtitle'
    },
    {
        component: HeaderSlide,
        header: 'Header'
    }
]

我现在有这段代码,我想添加更多扩展ISlide的接口,并在不手动编写联合类型的情况下自动更新数组的类型。是否有方法可以做到这一点,还是只能使用类来实现?

英文:

I have an array that can store objects that extend ISlide

interface ISlide {
    component: ComponentType;
}

interface ITitleSlide extends ISlide {
    title: string;
    subtitle: string;
}

interface IHeaderSlide extends ISlide {
    header: string;
}

const slides: (ITitleSlide | IHeaderSlide)[] = [
    {
        component: TitleSlide,
        title: 'Title',
        subtitle: 'Subtitle'
    },
    {
        component: HeaderSlide,
        header: 'Header'
    }
]

I have this code right now and I would like to add more interfaces that extend ISlide and update the type of the array automatically without having to write union manually. Is there a way to do this or is it only possible with classes?

答案1

得分: 1

你可以使用type关键字来创建一个联合类型,自动包含所有扩展ISlide的接口,看看这个例子:

type Slide = ITitleSlide | IHeaderSlide | IAnotherSlide;

const slides: Slide[] = [
    {
        component: TitleSlide,
        title: 'Title',
        subtitle: 'Subtitle'
    },
    {
        component: HeaderSlide,
        header: 'Header'
    },
    {
        component: AnotherSlide,
        // additional properties
    }
];

如你所见,通过将Slide类型定义为扩展ISlide的所有接口的联合,你可以简单地将Slide[]用作slides数组的类型!

更新

interface ITitleSlide {
    component: typeof TitleSlide;
    title: string;
    subtitle: string;
}

interface IHeaderSlide {
    component: typeof HeaderSlide;
    header: string;
}

interface IAnotherSlide {
    component: typeof AnotherSlide;
    // additional properties
}

type SlideTypeMap = {
    [key: string]: Slide;
};

const slides: SlideTypeMap = {
    TitleSlide: {
        component: TitleSlide,
        title: 'Title',
        subtitle: 'Subtitle'
    },
    HeaderSlide: {
        component: HeaderSlide,
        header: 'Header'
    },
    AnotherSlide: {
        component: AnotherSlide,
        // additional properties
    }
};

type Slide = SlideTypeMap[keyof SlideTypeMap];

如你所见,Slide类型是通过使用keyof SlideTypeMap来检索SlideTypeMap的所有可能键,然后访问相应的值生成的!

祝好运!

英文:

you can use the type keyword to create a union type that automatically includes all interfaces extending ISlide, check this out :

type Slide = ITitleSlide | IHeaderSlide | IAnotherSlide;

const slides: Slide[] = [
    {
        component: TitleSlide,
        title: 'Title',
        subtitle: 'Subtitle'
    },
    {
        component: HeaderSlide,
        header: 'Header'
    },
    {
        component: AnotherSlide,
        // additional properties
    }
];

as you see by defining the Slide type as a union of all interfaces that extend ISlide, you can simply use Slide[] as the type of the slides array!

update<br>

interface ITitleSlide {
    component: typeof TitleSlide;
    title: string;
    subtitle: string;
}

interface IHeaderSlide {
    component: typeof HeaderSlide;
    header: string;
}

interface IAnotherSlide {
    component: typeof AnotherSlide;
    // additional properties
}

type SlideTypeMap = {
    [key: string]: Slide;
};

const slides: SlideTypeMap = {
    TitleSlide: {
        component: TitleSlide,
        title: &#39;Title&#39;,
        subtitle: &#39;Subtitle&#39;
    },
    HeaderSlide: {
        component: HeaderSlide,
        header: &#39;Header&#39;
    },
    AnotherSlide: {
        component: AnotherSlide,
        // additional properties
    }
};

type Slide = SlideTypeMap[keyof SlideTypeMap];

as you see,the Slide type is generated by using the keyof SlideTypeMap to retrieve all the possible keys of the SlideTypeMap and then accessing the corresponding values!

good luck!

答案2

得分: 0

最好的方式来保存一组命名类型是使用接口映射:

interface SlideTypeMap {
  ITitleSlide: ITitleSlide;
  IHeaderSlide: IHeaderSlide
}
type AnySlide = SlideTypeMap[keyof SlideTypeMap];

let slides: AnySlide[] = [...]

你可以使用接口合并来同时在多个文件中保持接口,或者用它来获取带有它们名称的接口列表。

英文:

The best way to keep a bunch of named types is interface map:

interface SlideTypeMap {
  ITitleSlide: ITitleSlide;
  IHeaderSlide: IHeaderSlide
}
type AnySlide = SlideTypeMap[keyof SlideTypeMap];

let slides: AnySlide[] = [...]

You may use interface merging to keep interface in multiple files at once, or use it to get list of iterfaces with their names

huangapple
  • 本文由 发表于 2023年7月3日 02:04:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76600188.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定