【问题标题】:How to declare a type for object with one different key in TypeScript [duplicate]如何在 TypeScript 中为具有不同键的对象声明类型 [重复]
【发布时间】:2021-07-16 12:45:59
【问题描述】:

您好,我想为这样的对象创建一个类型:

const z = {
    name: { // this one is special
        buty: ['qqqq']
    },
    lipa: ['xxx'],
    // more keys here
};

基本上就是这样的对象

type Test = {
    [key: string]: string[]
}

除了一个小例外。它总是有一个值有点不同的键名。

type Special = {
    name: {
        [key: string]: string[]
    }
}

但是当我试图合并这两种类型时

type Test =
    { [key: string]: string[] } &
    { name: { [key: string]: string[] } };

const z: Test = {
    name: { // this one is special
        buty: ['qqqq']
    },
    lipa: ['xxx'],
    // more keys here
};

我收到一个错误Type '{ buty: string[]; }' is missing the following properties from type 'string[]': length, pop, push, concat, and 26 more.(2322)

是否可以为这样的对象创建类型?

TypeScript Playgroud

【问题讨论】:

  • @T.J. Crowder 我不认为这是同一个问题,原来的工作在特定的界面上,这个使用通用的字符串键。这应该重新打开,因为我相信没有人会使用您链接的那个来解决这个问题。

标签: typescript


【解决方案1】:

以下基于映射类型的解决方案:

type Test<T extends  { [key: string]: any }> =
    {
        [K in keyof T]:
            K extends 'name' ? { [key: string]: string[] } : string[]
    }

// id function to make type more accurate by generic
const makeTest = <T extends  { [key: string]: any }>(obj: Test<T>): Test<T> => obj
   

// correct use
const z = makeTest({
    name: { // this one is special
        buty: ['qqqq']
    },
    lipa: ['xxx'],
    // more keys here
});

// error as object wrong
const y = makeTest({
    name: ['xxx'], // no it is special
    lipa: ['xxx'],
    // more keys here
});

我们可以通过使用 id 函数 (x => x) 来实现需求,这将由于使用泛型类型而缩小类型。当我们使用泛型时,TS 有更好的收缩,而正是这个功能允许我们这样做。此外,您创建的类型也不起作用,因为 string | 'name' 键的计算结果为 string,因此交集的第二部分完全被省略了。

解决方案是使类型有条件,并为特殊的“名称”键设置不同的值类型。

playground

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-13
    • 2020-01-04
    • 2022-01-26
    • 2017-02-20
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    相关资源
    最近更新 更多