TypeScript如何从标签模板字面量函数泛型参数推导模板精确类型?
解决方案
- TypeScript 5.0及以上版本可以直接使用
const泛型修饰符,引导TypeScript保留模板参数的字面量元组类型,示例代码如下:
const tag = <const T extends ReadonlyArray<string>>(template: T, ...args: string[]) => { return {template, args}; }; const a = tag`hello ${'world'}`; // 推导结果: // const a: { // template: readonly ["hello ", ""]; // args: string[]; // }
- 如果使用的是5.0以下的TS版本,可以通过增加字符串字面量泛型约束实现同等效果:
const tag = <S extends string, T extends readonly S[]>(template: T, ...args: string[]) => { return {template, args}; }; const a = tag`hello ${'world'}`; // 同样可以得到精确的template字面量元组类型
默认TypeScript对数组类型的泛型参数会做类型加宽,推导为最宽泛的兼容类型(这里就是TemplateStringsArray),加上上述约束后,TS会保留传入的模板字符串的精确分段内容,不会做类型加宽。
如果需要去掉推导结果的readonly修饰,可以通过类型映射移除只读属性:
type Mutable<T> = { -readonly [P in keyof T]: T[P] }; const tag = <const T extends ReadonlyArray<string>>(template: T, ...args: string[]) => { return { template: template as Mutable<T>, args }; }; // 此时template的类型为可变元组 ["hello ", ""]
内容的提问来源于stack exchange,提问作者bjKim
相关产品推荐
相关产品推荐

