Typescript:如何从类的索引签名中排除方法



我有一个类可以由用户扩展,如下所示:

class Foo {
extendFoo(key: string, value: string) {
this[key] = value; //<==typescript error: missing index signature
}
}

正如您所看到的,this可以用字符串进行扩展。问题是typescript抱怨,因为我没有索引签名,所以我尝试添加一个:

class Foo {
[key: string]: string;
extendFoo(key: string, value: string) {  //<==typescript error: extendFoo is not a string
this[key] = value;
}
}

如何添加索引签名,但仍然允许类中的方法?

当然,我可以将索引签名更改为[key: string]: string | Function,但这是不正确的——任何未知密钥都必须是字符串。如何从索引签名中仅排除extendFoo

class Foo {
[key: string]: string | Function;
extendFoo(key: string, value: string) {
this[key] = value;
}
}
const test = new Foo();
test['some unknown prop'].includes('test'); //<== typescript error: 'Property 'includes' does not exist on type 'Function'

顺便说一句,我知道扩展this是一种糟糕的模式,但我正在将遗留代码转换为typescript,别无选择。

由于密钥的类型需要是stringnumber,我认为TS无法以完全类型安全的方式完全执行您想要的操作。由于您的方法是已知的和例外的,@ts-ignoreTS错误可能可以吗?

class Foo {
[key: string]: string | null;
// @ts-ignore
extendFoo(key: string, value: string) {
this[key] = value;
}
// @ts-ignore
}

const test = new Foo();
test['some unknown prop']?.includes('test'); // <- No error
test.extendFoo("asdf", "asdf"); // <- works, too

我知道这并不理想,但至少你不必在每个电话网站上都投。

最新更新