TypeScript:交叉类型vs子类化收窄Record<string, any>属性类型
泛型收窄外部类
user_data类型的正确方案 直接用泛型接口继承原类型,就能同时满足保留私有成员和严格限制user_data属性的需求:
// 泛型工具接口 interface NarrowUserData<T, U> extends T { readonly user_data: U; } // 使用示例 declare const foo: NarrowUserData<Foo, { a: string, b: number, }>; foo.user_data.a = "hello"; // ok foo.user_data.a = 1; // error - 符合预期 foo.user_data.c = "hello"; // error - 符合预期 doSomething(foo); // ok - 完美适配原类型
为什么之前的方法不行?
- 交叉类型方案:
Record<string, any>和具体类型交叉后,any会“覆盖”严格类型检查,导致额外属性仍能通过编译。 - Omit+交叉方案:
Omit本质是基于对象类型的键操作,会丢失类的私有成员信息,导致类型无法兼容原类。
而泛型接口继承的方式,完全复用了原类的所有成员(包括私有),只是精准重写了user_data的类型,完美规避了上述问题。
内容的提问来源于stack exchange,提问作者Levi Haskell
相关产品推荐
相关产品推荐

