![](/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.