属性类型取决于其他属性的类型

时间:2020-08-23 21:14:13

标签: typescript types

因此,我正在测试TypeScript可以走多远且似乎无法克服以下问题。 属性A具有某些值时,如何限制属性B的类型?

// The type I want to declare
type Bar<T> = {
    prop: keyof T; // Select a property of the type
    value: T[keyof T]; // Provide the value of that property, this currently does not work
}

// Some random interface
interface Foo {
    id: number;
    name: string;
}

let bar: Bar<Foo> = {
    prop: "name", // Selected Foo.name: string
    value: 9,     // Should only allow strings
};

在这种情况下,value的属性类型为number | string,但是由于所选属性name的类型为string,我想强制将其字符串化。 / p>


注释

我可以用这种方式声明它,但是该接口吸引力不大,清晰明了,并且更容易出错:应该只选择一个属性,并且由于缺少属性名,您实际上并不知道期望什么。或者我需要进一步嵌套对象。

type Bar<T> = {
    prop: {
        [K in keyof T]?: T[K];
    }
}

let bar: Bar<Foo> = {
    prop: {
        name: 'yay', // string is forced now
    }
};

2 个答案:

答案 0 :(得分:0)

这是因为Foo有两个键,一个是字符串,另一个是数字。因此,值是字符串|数。也许行得通吗?

foo.bar _

答案 1 :(得分:0)

根据您的用法示例:

let bar: Bar<Foo> = {
    prop: "name", // Selected Foo.name: string
    value: 9,     // Should only allow strings
};

编译器无法推断出我们需要name属性。它需要另一个类型参数,例如Pick实用程序类型。

type PickEntry<T, K extends keyof T> = {
    prop: K; // Select a property of the type
    value: T[K]; // Provide the value of that property, this currently does not work
}

注意:PickEntryFoo

更明确

然后,我们可以检测到无效的值类型:

let nameEntry: PickEntry<Foo, 'name'> = {
    prop: "name",
    value: 9,
//  ~~~~~ Error: Type 'number' is not assignable to type 'string'.(2322)
};