簡體   English   中英

打字稿無法轉換為通用類型變量

[英]typescript cannot cast to generic type variable

我想創建一個通用函數來在typescript-redux中創建動作。

我想要的是使用傳遞接口作為類型變量的函數。 所以我從這個功能開始:

function action<F>(type: string, payload: any): F {
    return { type, payload };
}

我想這樣使用它:

interface Login {
    type: LOGIN_REQUEST;
    payload: credentials;
}

const Login = (credentials: Credentials) 
     => action<Login>(LOGIN_REQUEST, credentials);

問題是有此錯誤:

Type '{ type: string; payload: any; }' is not assignable to type 'F'.

由於action是通用的,因此編譯器實際上無法知道對象文字{ type: string; payload: any; } { type: string; payload: any; } { type: string; payload: any; }將滿足類型F 此代碼也將是有效的調用:

action<{ type: string; payload: any; otherMandatoryProp: boolean }>(LOGIN_REQUEST, credentials);

在上述情況下, F具有多余的字段,因此無法執行action

最簡單的解決方案是在這種情況下突破類型安全沙箱並使用類型斷言:

function action<F>(type: string, payload: any): F {
    return { type, payload } as any;
}

此版本仍允許使用{ type: string; payload: any; otherMandatoryProp: boolean } { type: string; payload: any; otherMandatoryProp: boolean } { type: string; payload: any; otherMandatoryProp: boolean } ,這可能會使某些人對重新調整的對象上的字段進行一些假設。 如果要將F限制為僅具有typepayload的類型,則可以使用類型約束,該約束指定F存在屬性typepayload ,並且如果存在任何其他屬性,則它們的類型為never

function action<F extends { type : string, payload : any} & { [P in Exclude<keyof F, 'type' | 'payload'>]: never }>(type: string, payload: any): F {
    return { type, payload } as any;
}
const Login = (credentials: credentials) => action<Login>(LOGIN_REQUEST, credentials);
action<{ type: string; payload: any; otherMandatoryProp: boolean }>(LOGIN_REQUEST, {}) // invalid call

打字稿的返回值應與您要返回的對象匹配打字稿的返回值應為login類型(或者您可以將其設置為any)

function action<F>(type: string, payload: any): Login  {
    return { type, payload };
}

因為您將不會返回任何值,而只會返回Login ,所以您需要添加一個約束:

function action<F extends Login>(type: string, payload: any): F {
    return { type, payload } as F;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM