例子:
export interface Column<T> {
field: string;
columnFormatter?: (props: {
value: any/** field type inside T**/; data: T; node: any
}) => void;
}
field 是型別 T 內的屬性的名稱,我怎么能說該值是該型別?
export interface IPurchase {
id: string;
name: string;
purchaseDate: Date;
}
let doSomethingWithMyDate: (myDate: Date) => (true);
const columns: Array<Column<IPurchase>> = [
{
field: "purchaseDate", /* "purchaseDate" must be inside IPurchase */
columnFormatter: ({ value /* must identify that this is a Date */ }) =>
doSomethingWithMyDate(value)
}];
uj5u.com熱心網友回復:
為了表示引數的屬性和屬性field型別之間的相關性,你需要是一個聯合型別,其中每個鍵都有一個成員。例如,給定您的示例,您需要valuepropscolumnFormatterColumn<T>TIPurchaseColumn<IPurchase>
type ColumnIPurchase = {
field: "id";
columnFormatter?: ((props: {
value: string;
data: IPurchase;
node: any;
}) => void);
} | {
field: "name";
columnFormatter?: ((props: {
value: string;
data: IPurchase;
node: any;
}) => void)
} | {
field: "purchaseDate";
columnFormatter?: ((props: {
value: Date;
data: IPurchase;
node: any;
}) => void);
}
這將按需要運行:
const columns: Array<Column<IPurchase>> = [
{
field: "purchaseDate",
columnFormatter: ({ value }) => doSomethingWithMyDate(value)
},
{
field: "name",
columnFormatter: ({ value }) => doSomethingWithMyDate(value) // error!
// string isn't a Date ----------------------------> ~~~~~
}
];
所以這就是我們想要的……我們怎么寫Column<T>才能做到呢?
這是一種方法:
type Column<T> = { [K in keyof T]-?: {
field: K;
columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void;
} }[keyof T]
這種型別的一般形式{[K in keyof T]-?: F<K>}[keyof T],被稱為分布式物件型別,如microsoft/TypeScript#47109中所創造的;我們正在對in 的鍵創建一個映射型別keyof T,然后立即對其進行索引,keyof T以便為 in 中的每個鍵獲得一個并F<K>集。Kkeyof T
特別是在這里,我們正在計算{ field: K; columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void; }whereK是鍵T[K]的型別,以及與該鍵對應的屬性值的型別。
您可以驗證其Column<IPurchase>評估結果是否完全符合所需的型別。
Playground 代碼鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/497066.html
標籤:打字稿
