我正在现有的 JavaScript 代码库中工作。有一个类公开了预定义的函数(例如“复制”、“粘贴”)以供实用程序使用。该类可以使用“扩展”函数进行实例化,允许用户注册其他实用函数以供以后使用。
此代码未键入,因此我尝试向签名添加类型。但是我在通过名称获取实用函数的函数(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 文档中弄清楚如何使用 条件类型< /a>,例如 get(name: string | keyof Operation)
,我不相信这是正确的解决方案。
鉴于 name
不能保证是 get(name)
函数的最佳方法是什么>操作?
I'm working in an existing JavaScript codebase. There is a class which exposes pre-defined functions (e.g. "copy", "paste") for utility. The class can be instantiated with "extension" functions, which allow users to register other utility functions for later use.
This code isn't typed, so I'm trying to add types to the signatures. But I'm having a lot of trouble with the function that gets a utility function by name (get(name)
). A minimised version of the code (with my attempt at adding types) is as follows:
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 fails because of this[name]
: "Element implicitly has an 'any' type because type 'Operation' has no index signature ts(7053)".
Since this function is meant to accept arbitrary strings (because of the overrides), I don't think I can avoid typing the function as get(name: string)
. I couldn't figure out from the TypeScript documentation how to use conditional types, e.g. get(name: string | keyof Operation)
, and I'm not convinced that's the right solution.
What is the best way to (re-)structure and type the get(name)
function with strict types, given that name
is not guaranteed to be a property of Operation
?
发布评论
评论(1)
检查(在 JavaScript 中,而不是 TypeScript)正在访问的键是否是您想要允许的直接在类上的键之一 - 例如
copy
或paste
。然后,TS 将自动推断允许此类访问。Check (in JavaScript, not TypeScript) that the key being accessed is one of the ones directly on the class that you want to permit - eg
copy
orpaste
. Then, TS will automatically infer that such access is allowed.