TypeScript接口类似的属性



我正在做TS项目,我有复杂的类结构(抽象工厂)。问题是我的界面看起来像:

export interface IProduct {
customization: Customization;
preparation: Preparation;
make: () => void;
setMilk?: (volume: number) => void;
setWater?: (volume: number) => void;
setSugar?: (volume: number) => void;
}

所以,我有许多类似的setter属性(最后3),它需要更多,但模板是相同的。问题是:有没有办法把它们缩短成一行?看起来像:

['set*': string]: (volume: number) => void;

(可能是索引签名等的一些技巧)

如果您想接受以"set"开头的任何可能的密钥,包括您没有指定的内容,如"setFlour""setRandomThing""settingSun""set$$1234Blah":

在TypeScript 4.4之前,没有办法对特定的对象类型做到这一点。但是,现在支持模板字符串模式索引签名。索引签名的形式为{[dummyKeyName: KeyType]: ValueType},其中KeyType表示您希望签名应用的密钥类型。传统上,KeyType只能使用stringnumber。TS4.4允许使用形式为`set${string}`模式模板文字类型,由microsoft/TypeScript#40598实现,其中string是一个"pattern"或";placeholder"在模板文字类型中

对于你的例子,这意味着你可以这样写:

export interface IProduct {
customization: Customization;
preparation: Preparation;
make: () => void;
[k: `set${string}`]: (volume: number) => void
}

并进行测试:

declare const p: IProduct;
p.setMilk(1);
p.setSugar(2);
p.setWater(3);
p.setFlour(4); //okay

另一方面,如果您只想接受"milk""water""sugar",或其他特定字符串文字类型的枚举联合,则可以通过使用适当的KV类型扩展Record<K, V>实用程序类型来实现:

namespace ListOfKeys {type SetKeys = 'milk' | 'water' | 'sugar';

export interface IProduct extends Record<
`set${Capitalize<SetKeys>}`, (volume: number) => void
> {
customization: Customization;
preparation: Preparation;
make: () => void;
}

并进行测试:

declare const p: IProduct;
p.setMilk(1);
p.setSugar(2);
p.setWater(3);
p.setFlour(4); //error

Playground链接到代码

相关内容

  • 没有找到相关文章

最新更新