簡體   English   中英

TypeScript 未能使用 keyof 作為屬性從泛型中正確推斷類型

[英]TypeScript failing to correctly infer types from generic using keyof as property

我目前正在為驗證組件編寫一些 typedef 和類,該組件正在構建以驗證特定 class (下面的“主要”)上的字段。 目標:

  1. 每個驗證規則 ( MainValidationRule ) 應包含它正在驗證的密鑰 ( T extends keyof Main ),以及驗證相應值並返回指示有效性的標志的驗證 function ( (value: Main[T]) => boolean ) .
  2. 為了便於使用驗證器,在運行時,驗證規則數組將被組裝到 object 中,將每個字段( 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>

為了清楚起見,只需比較我的MainValidationRuleMainValidationRule<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.

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