我有一個組件需要兩個可能的回呼。應該傳遞的回呼取決于其他屬性,如果屬性型別以值 A 傳遞,那么它應該使用回呼 A,如果型別作為 B 傳遞,那么它應該使用回呼 B。為了表達這種二分法,我使用 sum整個 props 物件的型別,使用型別作為標簽。
我為選項卡嘗試了各種組合,但我無法讓 TS 識別我正在傳遞正確的回呼。
這是代碼的簡化:
import React from 'react'
type SessionDefinition = {name: string}
type SessionDefinitionFromDb = {name: string, id: string}
type CreateCb = (definition: SessionDefinition) => Promise<void>;
type UpdateCb = (definition: SessionDefinitionFromDb) => Promise<void>;
type Props =
| {
isLoading: boolean;
onSubmit: CreateCb;
definition: SessionDefinition;
action: 'create';
}
| {
isLoading: boolean;
onSubmit: UpdateCb;
definition: SessionDefinitionFromDb;
action: 'update';
}
export default function DefinitionForm(props: Props) {
return <div>'Test'</div>
}
<DefinitionForm
isLoading
onSubmit={(x:SessionDefinitionFromDb) => console.log(x)}
definition={{ id: 'test', name:'text'}}
action='update'
/
錯誤打字稿抱怨是:
Type '(x: SessionDefinitionFromDb) => void' is not assignable to type 'CreateCb | UpdateCb'.
Type '(x: SessionDefinitionFromDb) => void' is not assignable to type 'CreateCb'.
Types of parameters 'x' and 'definition' are incompatible.
Property 'id' is missing in type 'SessionDefinition' but required in type 'SessionDefinitionFromDb'.
這是一個游樂場示例
uj5u.com熱心網友回復:
錯誤訊息令人困惑,但問題似乎來自您的回呼回傳的事實void,而不是Promise<void>預期的那樣。因此,將上述回呼替換為(x: SessionDefinitionFromDb) => new Promise(() => console.log(x))似乎可以解決它,因為 Typescript 不再為我抱怨。
uj5u.com熱心網友回復:
問題源于 TypeScript 無法縮小提供給任一物件型別的 props 的范圍。你得到了
“SessionDefinition”型別中缺少屬性“id”,但在“SessionDefinitionFromDb”型別中是必需的。
錯誤,因為在 TS 耗盡型別評估并發現它不可能之后,TS 將首先識別一個不兼容的屬性并將其作為錯誤訊息。
如果您使傳遞的道具與第二個物件型別兼容 - 在哪里onSubmit-UpdateCb它會起作用。
<DefinitionForm
isLoading
onSubmit={(x: SessionDefinitionFromDb) => {
console.log(x);
return Promise.resolve();
}}
// ^^^^^^^^^^^^^^^
definition={{ id: 'test', name: 'text' }}
action='update'
/>
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/419269.html
標籤:
上一篇:任何人都可以建議一種解決這個Typescript怪癖的方法嗎?
下一篇:如何動態地使動態型別的屬性可選?
