首页 > 解决方案 > 在 Typescript 中定义静态可索引对象属性

问题描述

我想用一个对象属性编写一个可重用的 TypeScript 类,该属性具有索引的命名属性,可以在构造时定义,然后通过它们的名称进行修改。这些命名属性可能是接口的键,我的目的是使用此接口静态检查 set 函数是否存在不正确的键或迭代,例如:

class Container<T> {
    private attributes: {[name: keyof T]: any} = {};

    constructor(attributes: {[name: keyof T]: number}) {
        Object.entries(attributes).forEach(([name, value]) => {
            this.attributes[name] = {value: value, ...}; // 1 I want to add further properites to this object
        });
    }

    set(name: keyof T, value: number) {
        this.attributes[name].value = value; // 2
    }
}

但是上述方法不起作用,因为:

1:元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型“{}”。在“{}”类型上找不到带有“字符串”类型参数的索引签名。

2:类型'keyof T'不能用于索引类型'{}'

keyof 是否适用于泛型类,我可以在 TypeScript 中实现类似的功能吗?我正在使用 TypeScript 3.9.4

标签: typescriptobjectindexingkeyof

解决方案


要保留键的类型(所以它们是keyof T,而不是成为string),您可以使用for .. in循环:

class Container<T> {
    private attributes: {
        [name in keyof T]?: any
    } = {};

    constructor(attributes: {[name in keyof T]: number}) {
        for(let key in attributes) {
            let value = attributes[key];
            this.attributes[key] = { value: value, example: 7 };
        }
    }

    set(name: keyof T, value: number) {
        this.attributes[name].value = value; // 2
    }
}

推荐阅读