在 TypeScript 中向派生类型添加另一个值

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

我有这些接口

interface CommonAnimalProps {
    common: {
        size: number, 
        weight: number,
        origin: string,
    }
}

interface DogProps extends CommonAnimalProps {
    name: string
}

interface CatProps extends CommonAnimalProps {
    furious: boolean
}

interface BirdProps extends CommonAnimalProps {
    canFly: boolean
}

export enum AnimalType {
    dog = "dog",
    cat = "cat",
    bird = "bird",
}

export interface AnimalTypeToAnimalPropsMap {
    [AnimalType.dog]: (DogProps)[],
    [AnimalType.cat]: (CatProps)[],
    [AnimalType.bird]: (BirdProps)[]
}

export type AllAnimalValues<T> = T[keyof T]
export type AllAnimalTypesArray = AllAnimalValues<AnimalTypeToAnimalPropsMap>
export type AllAnimalTypes = AllAnimalValues<AnimalTypeToAnimalPropsMap>[0]
export type AllAnimalTypesArrayDiscriminating = AllAnimalTypes[]

AllAnimalTypesArrayDiscriminating
导致数组看起来像这样

const foo: AllAnimalTypesArrayDiscriminating[] = [
{
    name: "Bello",
    common: {
        size: 10,
        weight: 25,
        origin: "Knowhwere"

},
{
    furious: true,
    common: {
        size: 3,
        weight: 5,
        origin: "Anywhere"

},
{
    canFly: false,
    common: {
        size: 39,
        weight: 50,
        origin: "Somewhere"

},
]

是否可以使用

AllAnimalTypesArrayDiscriminating
,并从中创建一个新的类型/接口(
AllAnimalTypesArrayDiscriminatingModified
),其中结果数组
bar
中的每个元素都将另一个道具(
color: string
)添加到
CommonAnimalProps
,以便结果看起来像这样

const bar: AllAnimalTypesArrayDiscriminatingModified[] = [
{
    name: "Bello",
    common: {
        size: 10,
        weight: 25,
        origin: "Knowhwere",
        color: 'red',

},
{
    furious: true,
    common: {
        size: 3,
        weight: 5,
        origin: "Anywhere",
        color: 'brown',

},
{
    canFly: false,
    common: {
        size: 39,
        weight: 50,
        origin: "Somewhere",
        color: 'white',

},
]

注意,我无法修改原始的

CommonAnimalProps
以添加
color
作为可选参数。我也无法编辑
DogProps, CatProps, BirdProps
。我正在寻找一种使用
AllAnimalTypesArrayDiscriminating
(或我没有排除的任何其他类型)来添加此属性的方法。有办法做到这一点吗?

这里是一个游乐场

typescript
1个回答
0
投票

是的,您可以通过在 TypeScript 中使用映射类型和实用程序类型来实现这一点。由于您无法直接修改原始

CommonAnimalProps
或其他动物道具,因此您需要创建一个新类型,将
color
属性专门添加到所有现有动物类型中的
common
字段。

具体操作方法如下:

步骤:

  1. 创建一个新类型,通过添加
    common
    字段来扩展每种动物类型的
    color
    属性。
  2. 使用映射类型迭代
    AllAnimalTypesArrayDiscriminating
    并修改每种类型的
    common
    字段。

打字稿代码:

// Step 1: Create a helper type that adds color to the common property
type WithColor<T extends CommonAnimalProps> = Omit<T, 'common'> & {
    common: T['common'] & { color: string }
};

// Step 2: Map over each type in AllAnimalTypesArrayDiscriminating and apply WithColor
export type AllAnimalTypesArrayDiscriminatingModified = {
    [K in keyof AllAnimalTypesArray]: WithColor<AllAnimalTypesArray[K]>;
};

// Example usage:
const bar: AllAnimalTypesArrayDiscriminatingModified[] = [
    {
        name: "Bello",
        common: {
            size: 10,
            weight: 25,
            origin: "Knowhwere",
            color: 'red'
        }
    },
    {
        furious: true,
        common: {
            size: 3,
            weight: 5,
            origin: "Anywhere",
            color: 'brown'
        }
    },
    {
        canFly: false,
        common: {
            size: 39,
            weight: 50,
            origin: "Somewhere",
            color: 'white'
        }
    }
];

说明:

  • WithColor<T>
    :此类型将
    color
    字段添加到给定动物道具 (
    common
    ) 的
    T
    属性。
  • AllAnimalTypesArrayDiscriminatingModified
    :这是一个映射类型,它将
    WithColor
    变换应用于
    AllAnimalTypesArrayDiscriminating
    中的每种类型。

这样,您就可以创建一个新的数组类型,其中每个动物类型的

common
属性都添加了
color
字段,而无需修改原始
CommonAnimalProps

© www.soinside.com 2019 - 2024. All rights reserved.