使用字符串访问 TypeScript 可选对象属性
Accessing TypeScript Optional Object Properties With a String
我在现有的 JavaScript 代码库中工作。有一个 class 公开了实用程序的预定义功能(例如“复制”、“粘贴”)。 class可以用“扩展”函数实例化,允许用户注册其他实用函数以备后用。
此代码未键入,因此我正在尝试将类型添加到签名中。但是我在使用按名称获取实用程序函数 (get(name)
) 的函数时遇到了很多麻烦。代码的最小化版本(我尝试添加类型)如下:
class Operation {
private extensions: {[key: string]: () => void}
constructor(extensions: {[key: string]: () => void}) {
this.extensions = extensions;
}
get(name: string): () => void {
if (this[name]) {
return this[name].bind(this)
}
if (this.extensions[name]) {
return this.extensions[name].bind(this)
}
// default to copy
return this.copy.bind(this);
}
copy() {
console.log('copied');
}
paste() {
console.log('pasted');
}
}
const operation = new Operation({'cut': () => { console.log('cut'); }});
operation.get('cut')();
由于 this[name]
而失败:“元素隐式具有 'any' 类型,因为类型 'Operation' 没有索引签名 ts(7053)”。
由于此函数旨在接受任意字符串(由于覆盖),我认为我无法避免将函数键入 get(name: string)
。我无法从 TypeScript 文档中弄清楚如何使用 conditional types,例如get(name: string | keyof Operation)
,我不认为这是正确的解决方案。
鉴于 name
不能保证是 属性 的 属性,使用严格类型(重新)构造和键入 get(name)
函数的最佳方法是什么17=]?
检查(在 JavaScript 中,而不是 TypeScript)被访问的密钥是直接在 class 上您想要允许的密钥之一 - 例如 copy
或 paste
。然后,TS 会自动推断允许这样的访问。
get(name: string): () => void {
if (name === 'copy' || name === 'paste') {
return this[name].bind(this)
}
if (this.extensions[name]) {
return this.extensions[name].bind(this)
}
// default to copy
return this.copy.bind(this);
}
我在现有的 JavaScript 代码库中工作。有一个 class 公开了实用程序的预定义功能(例如“复制”、“粘贴”)。 class可以用“扩展”函数实例化,允许用户注册其他实用函数以备后用。
此代码未键入,因此我正在尝试将类型添加到签名中。但是我在使用按名称获取实用程序函数 (get(name)
) 的函数时遇到了很多麻烦。代码的最小化版本(我尝试添加类型)如下:
class Operation {
private extensions: {[key: string]: () => void}
constructor(extensions: {[key: string]: () => void}) {
this.extensions = extensions;
}
get(name: string): () => void {
if (this[name]) {
return this[name].bind(this)
}
if (this.extensions[name]) {
return this.extensions[name].bind(this)
}
// default to copy
return this.copy.bind(this);
}
copy() {
console.log('copied');
}
paste() {
console.log('pasted');
}
}
const operation = new Operation({'cut': () => { console.log('cut'); }});
operation.get('cut')();
由于 this[name]
而失败:“元素隐式具有 'any' 类型,因为类型 'Operation' 没有索引签名 ts(7053)”。
由于此函数旨在接受任意字符串(由于覆盖),我认为我无法避免将函数键入 get(name: string)
。我无法从 TypeScript 文档中弄清楚如何使用 conditional types,例如get(name: string | keyof Operation)
,我不认为这是正确的解决方案。
鉴于 name
不能保证是 属性 的 属性,使用严格类型(重新)构造和键入 get(name)
函数的最佳方法是什么17=]?
检查(在 JavaScript 中,而不是 TypeScript)被访问的密钥是直接在 class 上您想要允许的密钥之一 - 例如 copy
或 paste
。然后,TS 会自动推断允许这样的访问。
get(name: string): () => void {
if (name === 'copy' || name === 'paste') {
return this[name].bind(this)
}
if (this.extensions[name]) {
return this.extensions[name].bind(this)
}
// default to copy
return this.copy.bind(this);
}