抱歉標題不清楚,但我不知道如何盡快描述我的問題。
我有一些具有一個文字值的型別和具有這種型別的平面結構作為值的物件(簡化版本):
type SomeType<T = string> = { value: T };
type SomeTypeMapped = Record<string, SomeType>;
我想寫 helper (generic) 來告訴 TS
const a = helper({
A: { value: 'literal-1' },
B: { value: 'literal-2' }
})
具有以下型別:
const a: {
A: SomeType<"literal-1">;
B: SomeType<"literal-2">;
}
到目前為止,我找到的最接近的解決方案是
function helper<V extends string, K extends string>(val: { [key in K]: SomeType<V> }) {
return val;
}
const a = helper({
A: { value: 'asd' }.
B: { value: 'qwe' }
});
// -->
const a: {
A: SomeType<"asd" | "qwe">;
B: SomeType<"asd" | "qwe">;
}
如果我嘗試這樣修改助手:
function helper<
V extends string,
K extends string,
T extends { [key in K]: SomeType<V> }
>(val: T) {
return val;
}
它將整個映射轉換為常量文字型別:
const a: {
A: {
value: "asd";
};
B: {
value: "qwe";
};
}
這也接近我想要實作的目標,但我的第二點是可讀性,因為
const a: {
A: SomeType<"asd">;
B: SomeType<"qwe">;
}
對于更復雜的示例(具有比單個“值”更多的欄位)更具可讀性。
我能以某種方式告訴 TS 該欄位A的型別恰好是 ofSomeType<"asd">并且欄位B的型別為SomeType<"qwe">嗎?
uj5u.com熱心網友回復:
這是我的寫作方式helper():
const helper =
<T extends Record<keyof T, string>>(val: { [K in keyof T]: SomeType<T[K]> }) => val;
泛型型別引數是從 的鍵 到要傳遞到的相關文字型別的T映射。所以目的是當你打電話時valstring SomeType
const a = helper({
A: { value: 'literal-1' },
B: { value: 'literal-2' }
})
T將被推斷為{ A: "literal-1"; B: "literal-2" }。Thenval不是T直接型別,而是映射型別 {[K in keyof T]: SomeType<T[K]>}。
請注意,編譯器確實能夠從表單的同態映射型別T的值推斷型別。在當前版本的 TS 手冊中并沒有很好地記錄它,但是在手冊的現已棄用的 v1 中有一部分關于從映射型別進行推斷的部分描述了這一點。{[K in keyof T]: ...T[K]...}
無論如何,這意味著當您helper()在上面呼叫時,T可以正確推斷,并val推斷為這種型別:
/* const a: {
A: SomeType<"literal-1">;
B: SomeType<"literal-2">;
} */
如預期的。
Playground 代碼鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/460182.html
下一篇:根據型別從泛型呼叫動態函式
