簡體   English   中英

Typescript::相關通用約束

[英]Typescript :: Related Generic Constraints

React中,我有一個像這樣的通用接口:

interface BaseProps<T> {
  data: T;
}

我的代碼的使用者將擴展它以定義他們自己的PropsComponent

interface MyProps extends BaseProps<string> {
  ...
}
const MyComponent: React.FC<MyProps> = ({ data }) => {
  ...
}

我想編寫一個方法來接受這樣的組件並返回與MyComponent.data相同類型的值。 這就是我正在努力解決的問題。 我正在嘗試編寫此方法並將其調用為:

function myFunc<T, U extends BaseProps<T>>(component: React.FC<U>): T {
  return ...
}
const ret1 = myFunc(MyComponent);
const ret2 = myFunc<string, MyProps>(MyComponent);

ret2具有正確的類型string ,但ret結果是unknown類型。 有沒有一種方法可以在myFunc方法中強制執行約束,以便正確鍵入ret1而無需我在<>中顯式聲明類型?

更新

@futut 和@proton 都給出了(幾乎)相同的解決方案,在這種情況下顯然有效! 榮譽!

但是,我在這里編寫的示例代碼有點過分簡化了。 如果我將BaseProps接口更改為:

interface BaseProps<T> {
  callback: (value: T) => void;
}

然后我不能再使用U["data"] 在這種情況下,有沒有辦法能夠在MyComponent.callback中返回value

PS:很抱歉在這里轉移球門柱。 我不擅長過於簡單化。

TypeScript 不知道提供的類型U也可以告訴它T是什么。 您可以改為使用單個類型參數並使用索引訪問來獲取其data屬性的類型:

function myFunc<T extends BaseProps<any>>(component: React.FC<T>): T["data"] { 
    /* ... */ 
}

只需明確通知 typescript,該類型的BaseProps.data將是 function 返回值,如下所示:

function myFunc<T, U extends BaseProps<T>>(component: React.FC<U>): U['data'] {
  ...
}

這樣您就不必將類型傳遞給泛型語句 ( <> ),只要傳遞給myFunc的組件類型正確即可。


編輯:關於問題的第二個版本:這里的事情變得棘手。 您可以使用infer關鍵字指向回調的值,如下所示:

function myFunc<T extends BaseProps<any>>(
  component: React.FC<T>,
): T['callback'] extends (a: infer R) => void ? R : never {
...

檢查有關該關鍵字的文檔: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html

暫無
暫無

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

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