![](/img/trans.png)
[英]Declare a constructor to correctly infer generic type from (keyof) argument in TypeScript
[英]TypeScript failing to correctly infer types from generic using keyof as property
我目前正在為驗證組件編寫一些 typedef 和類,該組件正在構建以驗證特定 class (下面的“主要”)上的字段。 目標:
MainValidationRule
) 應包含它正在驗證的密鑰 ( T extends keyof Main
),以及驗證相應值並返回指示有效性的標志的驗證 function ( (value: Main[T]) => boolean
) .T in keyof Main
)映射到該字段的所有驗證規則數組( Array<MainValidationRule<T>>
) .但是,當我嘗試將 map 規則轉換為所需的結構(代碼如下)時,TypeScript 給出了類型錯誤:
我會假設,因為rule.key
的任何給定值都保證rule
將滿足約束(即,我們知道如果rule.key === 'foo'
,那么rule
將滿足MainValidationRule<'foo'>
類型, 'bar' 或可能添加到Main
的任何其他鍵也是如此),這將編譯得很好。 但相反,TypeScript 似乎正在檢查MainValidationRule<keyof Main>
的所有可能值是否是特定鍵的有效規則,如果鍵是'foo'
,則失敗,例如MainValidationRule<'bar'>
不是有效規則'foo'
- 盡管我們的限制意味着這永遠不可能。
難道我做錯了什么? 還是有另一種方法可以寫出這會導致 TypeScript 正確推斷出滿足約束? Main
class 經常更新新屬性,因此手動輸入並檢查每個可能的變化是不切實際的。 代碼如下。 提前致謝!
type Main = {
foo: string;
bar: number;
};
type MainValidationRule<T extends keyof Main> = {
key: T;
isValid: (value: Main[T]) => boolean;
};
type MainValidationRulesMap = { [ T in keyof Main ]?: Array<MainValidationRule<T>> };
const mainValidationRulesMap: MainValidationRulesMap = {};
const mainValidationRules: Array<MainValidationRule<keyof Main>> = [];
mainValidationRules.forEach(rule => {
mainValidationRulesMap[rule.key] = [ rule ]; // type error
});
有時最好使用聯合類型而不是Foo<keyof Bar>
為了清楚起見,只需比較我的MainValidationRule
和MainValidationRule<keyof Main>
。
看起來他們是平等的,但事實並非如此。
對於 TS,推斷簡單的聯合類型要容易得多。
這是代碼:
type Main = {
foo: string;
bar: number;
};
type Values<T> = T[keyof T]
type MainValidationRule = Values<{
[P in keyof Main]: {
key: P;
isValid: (value: Main[P]) => boolean;
}
}>
type Rules = Array<MainValidationRule>
type MainValidationRulesMap = Partial<{ [T in keyof Main]: Rules }>;
const mainValidationRulesMap: MainValidationRulesMap = {};
const mainValidationRules: Rules = [];
mainValidationRules.forEach(rule => {
mainValidationRulesMap[rule.key] = [rule]; // ok
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.