![](/img/trans.png)
[英]Typescript - Using generics to extend an interface with a property of union type
[英]Why does my interface fail to extend a union type in typescript
我有一个类型是两个接口的联合:
interface Foo {
a: string
}
interface Bar {
b: string
}
type Baz = Foo | Bar;
我想扩展它,但它给了我一个错误:
interface Qux extends Baz { // error!
// ---------------> ~~~
// An interface can only extend an object type or
// intersection of object types with statically known members.
c: string;
}
interface Qux extends Baz { // error!
c: string;
}
为什么我会收到该错误,我该怎么办?
具有更多上下文的问题的原始版本:
我编写了一个类型文件来扩充 npm 库中的Palette
类型定义文件。 (具体的材料用户界面)。 如果我尝试让ODPaletteColorOptions
扩展PaletteColorOptions
,如下面的代码所示,这不会成功扩展 PaletteColorOptions 接口。 结果如下:显然,ODPaletteColorOptions 接口只有附加键:
createPalette.d.ts
------------------
import { Palette as MuiPalette, PaletteColorOptions } from "@mui/material/styles/createPalette";
declare module "@mui/material/styles/createPalette" {
export interface ODPaletteColorOptions extends PaletteColorOptions {
1000: string,
white: string,
black: string,
0: string,
Search: string
}
export interface Palette extends MuiPalette{
neutrals: ODPaletteColorOptions,
};
}
这是现有 MUI 类型定义文件中对PaletteColorOptions
的定义。
export type PaletteColorOptions = SimplePaletteColorOptions | ColorPartial;
在哪里
export interface SimplePaletteColorOptions {
light?: string;
main: string;
dark?: string;
contrastText?: string;
}
export type ColorPartial = Partial<Color>;
export interface Color {
50: string;
100: string;
200: string;
300: string;
400: string;
500: string;
600: string;
700: string;
800: string;
900: string;
A100: string;
A200: string;
A400: string;
A700: string;
}
但是,如果我没有扩展 PaletteColorOptions,而是显式扩展 SimplePaletteColorOptions 和 ColorPartial,那么扩展就可以工作。
import { Palette as MuiPalette, SimplePaletteColorOptions, ColorPartial } from "@mui/material/styles/createPalette";
declare module "@mui/material/styles/createPalette" {
export interface ODPaletteColorOptions extends SimplePaletteColorOptions, ColorPartial {
1000: string,
white: string,
black: string,
0: string,
Search: string
}
export interface Palette extends MuiPalette{
neutrals: ODPaletteColorOptions,
};
}
为什么第一种方法会失败?
为了让编译器处理interface
类型(以及class
类型的实例,可以看作具有与类同名的interface
),它们需要有一组静态已知键。 联合类型有多组键,因此您不能将它们扩展为接口。 有关可以扩展哪些类型的事物(例如,object 类型和此类类型的交集)以及一些不能扩展的事物(例如,泛型类型参数)的描述,请参见microsoft/TypeScript#13604 。
这就是为什么您可以单独扩展Foo
或Bar
,但不能扩展联合Foo | Bar
Foo | Bar
。
幸运的是,您可以使用交集类型获得几乎相同的效果,如TS 手册文档中所述,类型别名和接口之间的差异:
type Qux = Baz & { c: string }; // okay
现在, Qux
的行为就像Baz
具有string
值的c
属性,这大概是您想看到的:
function processQux(q: Qux) {
console.log(("a" in q ? q.a : q.b).toUpperCase() + " " + q.c);
}
const q: Qux = { a: "hey", c: "you" } // okay
processQux(q) // HEY you
processQux({ b: "it's", c: "me" }) // IT'S me
processQux({ c: "oops" }) // error!
// Argument of type '{ c: string; }' is not assignable to parameter of type 'Qux'.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.