将对象属性限制为 keyof 接口

2024-03-05

此代码将无法编译:

interface IFoo {
   a: number;
}

type TFoo = keyof IFoo;
type OFoo = { [key: TFoo]: any };

let obj: OFoo = { a: 1 };

我想要实现的是 obj 只能与具有有效属性的对象一起分配,就像我写的那样:

let obj: IFoo = { a: 1};

但我需要通过 keyof 来完成。

感谢您的任何想法。


虽然你不能直接使用任何东西,但string or number作为索引签名中的键类型(以及您的定义OFoo会给你一个错误),你can将键限制为 的子类型string using 映射类型 https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types. Since TFoo,又名keyof Foo, 是一个子类型string,您可以使用这样的映射类型:

type OFoo = { [K in TFoo]: any }; 

请注意,映射类型的语法与常规索引签名的语法不同。这TFoo上面对应的是允许的键的类型,也就是"a"在你的情况下,但也可以是字符串文字的联合,例如"a"|"b"|"c", 甚至string。还有K上面是一个参数,对应于type每个属性的密钥。 (你并不真正关心K由于每个属性的类型value is any与 无关K,但你可以使用K如果您愿意的话,可以选择特定的属性。)无论如何,让我们使用它:

let obj: OFoo = { a: 1 }; // okay
let obj = { }; // error, property 'a' is missing
let obj = { c: 1 }; // error, excess property 'c'

顺便说一句,我可能会使用内置标准库类型Record<K,T>其定义如下:

type Record<K extends string, T> = {
  [P in K]: T
}

或者,你可以这样想:“一个Record<K, T>是一个对象,其中每个键都在K每个值都是一个T“。 以及对于你,K is TFoo, and T is any:

type OFoo = Record<TFoo, any>;  // same thing 

希望有帮助;祝你好运!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将对象属性限制为 keyof 接口 的相关文章

随机推荐