TypeScript模板字面量中为何需要string & keyof Type写法?
核心原因
string & keyof Type的作用是过滤掉keyof Type返回值里的非字符串类型键,避免模板字面量类型报错。
原理说明
keyof 操作符返回的是目标类型所有键的联合类型,取值范围是 string | number | symbol,而非只有字符串:
- 当类型包含数字索引键、symbol类型键时,
keyof Type的联合类型中就会出现number、symbol类型的值 - 模板字面量类型仅支持嵌入
string | number | bigint | boolean | null | undefined类型的值,symbol类型无法嵌入模板字面量,会直接触发类型错误
string & keyof Type的写法做了一次类型交集计算:
- 字符串类型的键和
string取交集,还是原字符串字面量类型 - number、symbol类型的键和
string取交集,结果为never,会被自动从联合类型中排除
最终剩下的都是可安全嵌入模板字面量的字符串类型键,不会触发类型错误。
错误示例对比
如果去掉string &直接写${keyof Type}Changed,当类型存在symbol键时就会报错:
// 示例类型包含symbol键 type TestObj = { name: string; [Symbol.id]: string; } // 直接使用keyof会触发报错:Type 'symbol' is not assignable to type 'string | number | bigint | boolean | null | undefined' type BadEventName<Type> = `${keyof Type}Changed` // 增加string &过滤后无报错 type GoodEventName<Type> = `${string & keyof Type}Changed`
如果你希望同时保留数字类型的键(数字字面量可正常嵌入模板字面量,会自动转成对应字符串),也可以把过滤条件改成Extract<keyof Type, string | number>,效果和需求匹配即可。
内容的提问来源于stack exchange,提问作者Dalton Sweeney
相关产品推荐
相关产品推荐

