[英]Enforce single required property on Typescript interface, allow others
我正在創建一個通用的 WebSocket 組件。 我想要求Message
類型具有一個名為type
的必需屬性。
export type Message = {
type: string;
[key: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
};
該組件被賦予了一系列回調函數,當調用適當type
的Message
時會調用這些回調函數。
export interface Listeners {
[type: string]: (msg: Message) => void;
}
WebSocket 實現的代碼片段:
...
ws.onmessage = (event: MessageEvent): void => {
console.log("[websocket] got raw message", event.data);
try {
const msg = JSON.parse(event.data);
if (listeners[msg.type]) {
console.log("[websocket] got message", msg);
listeners[msg.type](msg);
}
}
}
...
在使用 WebSocket 組件時,我想定義一個自定義類型是Message
類型的擴展,並包含type
屬性。
interface GraphMessage extends Message {
id: string;
type: "initial" | "update";
chartType: "line" | string;
data: GraphPoint[];
}
我正在嘗試像這樣使用組件:
const handleUpdate = (msg: GraphMessage) => {}
const handleInitial = (msg: GraphMessage) => {}
const ws = await websocket("ws://localhost:9999/", {
initial: handleInitial,
update: handleUpdate
});
但是,我收到了一個打字稿錯誤:
TS2322: Type '(msg: GraphMessage) => void' is not assignable to type '(msg: Message) => void'.
Types of parameters 'msg' and 'msg' are incompatible.
Type 'Message' is not assignable to type 'GraphMessage'.
如何使Message
可分配到類型GraphMessage
?
編輯:我相信我已經找到了使Message
成為通用類型的解決方案。
type Message<T> = {
type: string
[key: string]: any
} & T
interface GraphMessage {
graphName: string
}
type Callback = (msg: Message<GraphMessage>) => void
const myBaseMessage = {
t...
TypeScript 正確地指出Type '(msg: GraphMessage) => void' is not assignable to type '(msg: Message) => void'
。
如果您的處理程序依賴於GraphMessage
但您只提供了一個Message
,這可能會導致運行時異常:
// Can, but doesn't have to include `id`
export type Message = {
type: string;
[key: string]: any;
};
interface GraphMessage extends Message {
id: string;
type: "initial" | "update";
}
const message: Message = {
type: 'foo',
}
const handler = (msg: GraphMessage): void => {
console.log(msg.type.toLocaleLowerCase());
}
如果我們這樣做
handler(message); // Compile-time error
TypeScript 將防止拋出異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.