TypeScript中如何对Symbol.for做类型标注解决跨文件类型报错
错误原因
你的代码报错的核心是:TypeScript的类型系统中,每一处独立调用Symbol.for()返回值的默认类型都是独立的unique symbol,哪怕传入的key完全相同,TS也不会在类型层面对比key的内容判定为同一类型。因此a.ts和b.ts中的两个sym属于不同的类型键,导致C实例不匹配I接口的定义。
方案1:抽离公共Symbol定义(全版本兼容,最推荐)
将全局Symbol的定义统一放到单独的公共文件中导出,所有使用的地方都引入同一个实例,TS自然会识别为同一类型:
- 新建
symbols.ts:
export const sym = Symbol.for('sym');
- 修改
a.ts:
import { sym } from './symbols'; interface I { [sym]: number } export declare function f(i: I): void;
- 修改
b.ts:
import { sym } from './symbols'; export class C { get [sym]() { return 1; } }
修改后c.ts的调用不会再出现类型错误。
方案2:显式统一类型(无需抽离公共文件)
如果不方便新增公共文件,可以在两处使用Symbol的地方手动指定为同一个unique symbol类型,TS3.6也支持该写法:a.ts修改为:
// 全局声明唯一的sym类型 declare const sym: unique symbol; // 手动断言Symbol.for返回值为上面声明的类型 const _sym = Symbol.for('sym') as unknown as typeof sym; interface I { [_sym]: number } export declare function f(i: I): void;
b.ts修改为:
// 同一份类型声明 declare const sym: unique symbol; const _sym = Symbol.for('sym') as unknown as typeof sym; export class C { get [_sym]() { return 1; } }
版本说明
截至当前所有正式版TypeScript,都不会自动合并相同key的Symbol.for返回值类型,TS的类型检查阶段不会解析Symbol.for的入参字符串做匹配,必须手动保证类型一致。
内容的提问来源于stack exchange,提问作者whitestripe
相关产品推荐
相关产品推荐

