如何在TypeScript中使用一个不同的键为对象声明类型

如何在TypeScript中使用一个不同的键为对象声明类型,typescript,Typescript,您好,我想为如下对象创建一个类型: const z = { name: { // this one is special buty: ['qqqq'] }, lipa: ['xxx'], // more keys here }; 事实上,它是这样一个物体 type Test = { [key: string]: string[] } 只有一个小例外。它总是有一个键名,值稍有不同 type Special = { name: {

您好,我想为如下对象创建一个类型:

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
};
我收到一个错误
类型“{buti:string[];}”缺少类型“string[]”中的以下属性:长度、弹出、推送、concat和26更多。(2322)

可以为这样的对象创建类型吗


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

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
});
型式试验=
{
[K in keyof T]:
K扩展'name'?{[key:string]:string[]}:string[]
}
//id函数,通过泛型使类型更精确
常量makeTest=(obj:Test):Test=>obj
//正确使用
常数z=makeTest({
名字:{//这是一个特别的
丁基:['qqqq']
},
利帕:['xxx'],
//这里还有钥匙
});
//对象错误
常数y=makeTest({
名称:['xxx'],//不,它是特殊的
利帕:['xxx'],
//这里还有钥匙
});
我们可以通过使用id函数(x=>x)来实现这一需求,这将由于使用泛型类型而缩小类型。当我们使用泛型时,TS有更好的缩小范围,而正是这个函数允许我们这样做。另外,由于
string |“name”
键的计算结果为
string
,因此交叉点的第二部分被完全忽略,因此您所创建的类型也不起作用

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


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