typescript - protected 属性的通用 getter 和 setter

标签 typescript

考虑这个 TypeScript 类,它通过将实现拆分为父类(super class)和子类来提供类型检查的通用 getter 和 setter:

class ICompetence {
    protected _id : number | undefined;
    protected name: string | undefined;
}

export default class Competence extends ICompetence {

    set<K extends keyof ICompetence>(key: K, value: ICompetence[K]): void {
        this[key] = value;
    }

    get<K extends keyof ICompetence>(key: K) : ICompetence[K] {
        return this[key];
    }

    constructor() {
        super();
    }
}

这个类是这样使用的:

let competence = new Competence():    
competence.set("name", "name value text");

但是,然后我收到此错误:

error TS2345: Argument of type '"name"' is not assignable to parameter of type

可以通过从接口(interface)类中删除 protected 注释来克服该错误:

class ICompetence {
    _id : number | undefined;
    name: string | undefined;
}

TypeScript 是否提供任何功能来避免这种在属性 protected 时发生的错误?

最佳答案

protected仅在设计时产生错误并且不会在运行时阻止访问,您可能会以另一种方式获得类似的行为,即通过隐藏导出类型中的相关属性,如下所示:

首先,将父类的属性公开:

class ICompetence {
  _id: number | undefined;
  name: string | undefined;
}

然后正常扩展该类,但不要导出它,并将其重命名为_Competence。 (“真正的”Competence 稍后会出现)

class _Competence extends ICompetence {

  otherProperty: string = "hmm"; // demonstrate you can add other things

  set<K extends keyof ICompetence>(key: K, value: ICompetence[K]): void {
    this[key] = value;
  }

  get<K extends keyof ICompetence>(key: K): ICompetence[K] {
    return this[key];
  }

  constructor() {
    super();
  }
}

现在我们准备Competence .首先,我们定义类型函数Omit , 它从类型中删除指定的键:

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>

然后我们导出一个名为Competence的接口(interface)和一个名为 Competence 的值, 来自 _Competence但不要公开 ICompetence 中的属性.当然,它们仍然存在,但类型系统不会公开它们:

export interface Competence extends Omit<_Competence, keyof ICompetence> { }
export const Competence = _Competence as new () => Competence;

现在在你的消费者代码中你应该能够做这样的事情:

const competence = new Competence();
competence.name // error at compile time
competence.otherProperty // okay
const name = competence.get("name") // string or undefined

而且它有效。希望有所帮助。祝你好运!

关于typescript - protected 属性的通用 getter 和 setter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50585492/

相关文章:

typescript - 使用 Typescript 的 http 发布请求

javascript - 操作数组 ["delete", "cancel"] 和由字符串 "01"确定的权限

typescript 歧视联盟允许无效状态

typescript - 如何根据键将函数的参数键入为对象值

javascript - Angular - 模板中调用的模型方法在无限循环中执行

angular - 如何在代码中创建 Angular 模板引用

typescript - 如何正确声明 typescript 中的类型

typescript - 为什么 ES2015 类不能在 TypeScript 中可靠地转译?

typescript - 具有通用叶包装器的可重用模型特定树结构

typescript - 如何根据两个属性对对象数组进行分组