只接受给定对象的键
Only accept keys of a given object
我正在尝试创建一个 TypeScript class,它用一个对象初始化,并且有一个方法只能将该对象的键作为参数。所以:
class MyClass {
properties = {};
constructor(properties) {
this.properties = properties;
}
// Passed propNames should only be keys of this.properties
pick(...propNames) {
return propNames.reduce((obj, name) => ({
...obj,
[name]: this.properties[name]
}), {});
}
}
这似乎与 this problem 类似,但我不知道如何在这种情况下应用它,因为属性是从外部传入的。
const props = { key: 'value', key2: 'value2' };
interface PropKeys {
key: string;
key2: string;
}
type KeyName = keyof(PropKeys);
// But what do I do to the class to get this to work?
const instance = new MyClass(props);
instance.pick('key', 'key2'); // Great
instance.pick('key3'); // Should throw a type error
这可能吗?有没有办法在不显式定义 InstanceKeys
的情况下做到这一点,而是从初始化实例时传递的 props 派生它们?
我正在努力研究泛型,并且在想可能是这样的:
class MyClass {
properties = {};
constructor<Type>(properties: Type) {
this.properties = properties;
type TypeKeys = keyof(Type);
}
pick(...propNames: TypeKeys[]) {
return propNames.reduce((obj, name) => ({
...obj,
[name]: this.properties[name]
}), {});
}
}
但这会引发两种类型的错误:
- 关于
<Type>
:“类型参数不能出现在构造函数声明中。”
- 关于
TypeKeys[]
:“找不到名称 'TypeKeys'。” (我的意思是,有道理;它超出了范围。)
UPDATE:这感觉更接近了,但我 运行 遇到了一个问题,属性首先在 class 上定义(在构造函数之上):
class MyClass<PropType extends Properties> {
properties: PropType = {};
constructor(properties: PropType) {
this.properties = properties;
}
pick(...propNames: Array<keyof(PropType)>) {
return propNames.reduce((obj, name) => ({
...obj,
[name]: this.properties[name]
}), {});
}
}
我 运行 在该行遇到的 TS 错误是
Type '{}' is not assignable to type 'PropType'. '{}' is assignable to the constraint of type 'PropType', but 'PropType' could be instantiated with a different subtype of constraint 'Properties'
这里的问题是任何传入的 properties
都可能有自己的键,但必须是 Properties 类型的实例,这会限制值。
您的泛型类型需要在 class
声明中进行,而不是在其构造函数中进行。那么 keyof Type
需要是匿名类型。您还需要键入 properties
,以便 TypeScript 知道它可以用 keyof Type
进行索引,我在这个示例中通过给它一个 Partial<Type>
.
类型来完成
我还使用了类型断言,因此 reduce
的初始 {}
对象被键入为 Partial<Type>
,因此 TypeScript 将理解如何在它被创建后对其进行索引已创建。
class MyClass<Type> {
properties: Partial<Type> = {};
constructor(properties: Type) {
this.properties = properties;
}
pick(...propNames: (keyof Type)[]) {
return propNames.reduce((obj, name) => ({
...obj,
[name]: this.properties[name]
}), {} as Partial<Type>);
}
}
我正在尝试创建一个 TypeScript class,它用一个对象初始化,并且有一个方法只能将该对象的键作为参数。所以:
class MyClass {
properties = {};
constructor(properties) {
this.properties = properties;
}
// Passed propNames should only be keys of this.properties
pick(...propNames) {
return propNames.reduce((obj, name) => ({
...obj,
[name]: this.properties[name]
}), {});
}
}
这似乎与 this problem 类似,但我不知道如何在这种情况下应用它,因为属性是从外部传入的。
const props = { key: 'value', key2: 'value2' };
interface PropKeys {
key: string;
key2: string;
}
type KeyName = keyof(PropKeys);
// But what do I do to the class to get this to work?
const instance = new MyClass(props);
instance.pick('key', 'key2'); // Great
instance.pick('key3'); // Should throw a type error
这可能吗?有没有办法在不显式定义 InstanceKeys
的情况下做到这一点,而是从初始化实例时传递的 props 派生它们?
我正在努力研究泛型,并且在想可能是这样的:
class MyClass {
properties = {};
constructor<Type>(properties: Type) {
this.properties = properties;
type TypeKeys = keyof(Type);
}
pick(...propNames: TypeKeys[]) {
return propNames.reduce((obj, name) => ({
...obj,
[name]: this.properties[name]
}), {});
}
}
但这会引发两种类型的错误:
- 关于
<Type>
:“类型参数不能出现在构造函数声明中。” - 关于
TypeKeys[]
:“找不到名称 'TypeKeys'。” (我的意思是,有道理;它超出了范围。)
UPDATE:这感觉更接近了,但我 运行 遇到了一个问题,属性首先在 class 上定义(在构造函数之上):
class MyClass<PropType extends Properties> {
properties: PropType = {};
constructor(properties: PropType) {
this.properties = properties;
}
pick(...propNames: Array<keyof(PropType)>) {
return propNames.reduce((obj, name) => ({
...obj,
[name]: this.properties[name]
}), {});
}
}
我 运行 在该行遇到的 TS 错误是
Type '{}' is not assignable to type 'PropType'. '{}' is assignable to the constraint of type 'PropType', but 'PropType' could be instantiated with a different subtype of constraint 'Properties'
这里的问题是任何传入的 properties
都可能有自己的键,但必须是 Properties 类型的实例,这会限制值。
您的泛型类型需要在 class
声明中进行,而不是在其构造函数中进行。那么 keyof Type
需要是匿名类型。您还需要键入 properties
,以便 TypeScript 知道它可以用 keyof Type
进行索引,我在这个示例中通过给它一个 Partial<Type>
.
我还使用了类型断言,因此 reduce
的初始 {}
对象被键入为 Partial<Type>
,因此 TypeScript 将理解如何在它被创建后对其进行索引已创建。
class MyClass<Type> {
properties: Partial<Type> = {};
constructor(properties: Type) {
this.properties = properties;
}
pick(...propNames: (keyof Type)[]) {
return propNames.reduce((obj, name) => ({
...obj,
[name]: this.properties[name]
}), {} as Partial<Type>);
}
}