我知道在 TS 中实现 Union Types 是不可能的,这是绝对合理的。但我可能正在寻找类似的东西/其他:
type TypeA = { a: string, b?: string }
type TypeB = { a: string, c?: string }
type UnionType = TypeA | TypeB;
type IntersectionType = TypeA & TypeB;
// Error:
// A class can only implement an object type or intersection of object types with statically known members.(2422)
class UnionClass implements UnionType {
checkUnionProperties() {
let x: UnionType = { a: '' };
}
a = 'a';
}
//This is possible
class IntersectClass implements IntersectionType {
checkUnionProperties() {
let x: IntersectionType = { a: '' };
}
a = 'a';
}
Run Code Online (Sandbox Code Playgroud)
我希望能够实现一个类型/接口,它具有类型共有的所有属性(仅在本例中a: string),但实际上并不是 TypeA 或 TypeB 的类。有我正在寻找的语言功能吗?
在此评论中,jcalz指出了以下事实:Pick<T, keyof T>whenT是联合类型提供了一种仅具有公共部分的类型:
type TypeA = { a: string; b?: string; };\ntype TypeB = { a: string; c?: string; };\ntype UnionType = TypeA | TypeB;\n\ntype Common<T> = Pick<T, keyof T>;\n\ntype X = Common<UnionType>;\n// ^? \xe2\x88\x92 type X = { a: string; }\nRun Code Online (Sandbox Code Playgroud)\n游乐场链接。(为了避免疑问,即使其他属性\xc2\xa0\xe2\x80\x94和在您的示例中\xc2\xa0\xe2\x80\x94 不是可选的,情况也是如此。)bc
你可以implement得到结果:
type TypeA = { a: string; b?: string; };\ntype TypeB = { a: string; c?: string; };\ntype UnionType = TypeA | TypeB;\n\ntype Common<T> = Pick<T, keyof T>;\n\nclass UnionClass implements Common<UnionType> {\n checkUnionProperties() {\n let x: UnionType = { a: \'\' };\n console.log(x);\n }\n\n a = "a";\n}\nRun Code Online (Sandbox Code Playgroud)\n\n这是类中没有的示例a = "a";,因此该类没有正确实现接口\xc2\xa0\xe2\x80\x94,这确实是一个错误,正如您所希望的那样。
用户makeitmore human在评论中指出了这个问题,其中有来自qiu 的出色答案,如果和都有一个名称相同但类型不同的属性,则以不同的方式处理它。例如,如果您有in but in ,则上面的结果将产生带有 的类型。这可能是您想要的,但如果不是,qiu 的答案已经为您介绍了该类型(有关详细信息,请参阅答案),这将完全省略:TypeATypeBx: stringTypeAx: numberTypeBCommon<TypeA | TypeB>x: string | numberSharedPropertiesx
// `OmitNever` and `SharedProperties` from: https://stackoverflow.com/a/68416189/157247\ntype OmitNever<T extends Record<string, unknown>> = {\n [K in keyof T as T[K] extends never ? never : K]: T[K];\n};\ntype SharedProperties<A, B> = OmitNever<Pick<A & B, keyof A & keyof B>>;\nRun Code Online (Sandbox Code Playgroud)\n你class可以这样使用它:
class UnionClass implements SharedProperties<TypeA, TypeB> {\n checkUnionProperties() {\n let x: UnionType = { a: "" };\n console.log(x);\n }\n\n a = "a";\n}\nRun Code Online (Sandbox Code Playgroud)\n\nTypeA它对和显示的没有影响TypeB,因为它们不具有相同名称但不同类型的属性(如x我上面的描述),但如果它们有\xc2\xa0\xe2\x80 就会有区别\x94Common<TypeA | TypeB>将包含xas string | number,但SharedProperties<TypeA, TypeB>完全忽略它。
| 归档时间: |
|
| 查看次数: |
516 次 |
| 最近记录: |