我有一个具有以下界面的对象,我想以编程方式更新它:
interface ITypes {
num: number;
str: string;
bol: boolean;
};
const obj: Partial<ITypes> = {}; // I want to update this programatically
我希望能够定义 akey
和 aval
并obj
使用这些值更新我。我希望它key
只能是ITypes
界面中的键之一,然后该值需要是key
从界面中选择的指定类型。我可以使用以下代码很好地做到这一点:
const key: keyof ITypes = "num"; // key must be a key from the ITypes interface
const val: ITypes[typeof key] = 1; // val must be the type specified at `"num"` - `number`
obj[key] = val;
上面的代码工作正常,但是,现在,我想在一个对象中定义它们,而不是将key
和val
作为单独的变量,因此我需要定义一个接口。但是,我在val
. 这是我迄今为止尝试过的:
interface IUpdatePayload {
key: keyof ITypes;
val: ITypes[typeof this.key]; // Type 'any' cannot be used as an index type.
};
const updatePayload: IUpdatePayload = {key: "num", val: "1"}; // should complain that `val` is not a number
obj[updatePayload.key] = updatePayload.val;
我尝试使用自引用接口的key
类型typeof this.key
(我在这个答案中看到了建议)但是这是错误的Type 'any' cannot be used as an index type.
,我猜这是因为键实际上没有被定义为具有第一个工作示例中的值使用变量。我的问题是,有没有办法使这项工作能够val
采用接口中key
指定的定义的类型ITypes
?
您可以使用映射类型从任何类型生成键/值对的联合:
type KVPairs<T, K extends keyof T = keyof T> =
K extends keyof T
? { key: K, val: T[K] }
: never;
然后,您可以创建自定义联合:
// {key: "num", val: number} | {key: "str", val: string} | {key: "bol", val: boolean}
type IUpdatePayload = KVPairs<ITypes>;
如果需要,此类型还允许您选择键的子集:
// {key: "num", val: number} | {key: "str", val: string}
type NumOrStr = KVPairs<ITypes, "num"|"str">
但是,将对象文字分配给联合类型时,错误并不总是很清楚:
const obj: IUpdatePayload = { key: "num", val: "1" };
/*
Type '{ key: "num"; val: string; }' is not assignable to type 'IUpdatePayload'.
Type '{ key: "num"; val: string; }' is not assignable to type '{ key: "bol"; val: boolean; }'.
Types of property 'key' are incompatible.
Type '"num"' is not assignable to type '"bol"'.
*/
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句