簡體   English   中英

Typescript 錯誤:擴展推斷類型可防止 TS Linting 錯誤(提供了 Playground 示例)

[英]Typescript Bug: Extending An Inferred Type Prevents TS Linting Errors (Playground Example Provided)

我有一個名為myStyles的函數,它接受一個參數。 此參數是一個包含baseStyles對象和styleVariants對象的對象。 它只是返回styleVariants對象。

function myStyles<StyleVariants extends StyleVariantsStructure>(params: {
  baseStyles: AllowedStyles;
  styleVariants: StyleVariants;
}): StyleVariants {
  return params.styleVariants;
}

它是這樣調用的:

myStyles({
  baseStyles: {
    color: 'red',
    backgroundColor: 'red',
  },
  styleVariants: {
    color: {
      red: {
        color: 'red',
        backgroundColor: 'red',
      },
    },
  },
});

baseStyles對象的類型為AllowedStyles ,它決定了我們允許使用哪些 css 屬性和值。 這很完美,如果在調用myStyles函數時 CSS 屬性或值拼寫錯誤,我們會得到正確的 TS 錯誤,例如

type AllowedStyles = {
  color?: 'red';
  backgroundColor?: 'red';
};

styleVariants對象的類型為StyleVariantsStructure 這實質上決定了它應該接受一個或多個包含AllowedStyles嵌套對象,例如

type StyleVariantsStructure = {
  [k: string]: {
    [k: string]: AllowedStyles;
  };
};

myStyles函數中,我們對styleVariants參數對象使用類型推斷。 這意味着,我們會自動獲取傳遞給myStyles函數的styleVariants的確切類型。 然后我們使用styleVariants類型作為函數的返回類型。 這對我們來說是必需的,因為我們需要知道myStyles的確切返回類型。 這是我們的功能:

function myStyles<StyleVariants extends StyleVariantsStructure>(params: {
  baseStyles: AllowedStyles;
  styleVariants: StyleVariants;
}): StyleVariants {
  return params.styleVariants;
}

這是類型推斷返回類型的示例,取自我用來演示此問題Typescript 游樂場

在此處輸入圖片說明

問題

如您所見,我需要使用StyleVariantsStructure類型來限制在styleVariants對象中傳遞的styleVariants ,例如我們必須只接受AllowedStyles 但是,我們還需要使用從styleVariants推斷出的類型作為myStyles函數的返回類型。 我試圖通過使用StyleVariants extends StyleVariantsStructure來解決這個StyleVariants extends StyleVariantsStructure 這在一定程度上起作用,但是在調用myStyles時, styleVariants參數對象中未突出顯示某些 Typescript 錯誤。

例如,如果color拼寫錯誤,我們不會得到 TS 錯誤:

在此處輸入圖片說明

但是,我確實得到了類型建議:

在此處輸入圖片說明

而且,如果值拼寫錯誤,我確實會收到錯誤消息:

在此處輸入圖片說明

本質上,對我來說,似乎我需要找到一種替代方法來對styleVariants對象使用類型推斷,同時還使用StyleVariantsStructure類型對其進行限制。 對此的任何幫助將不勝感激。

Typescript 操場中問題的最小演示

嚴格來說,這看起來是正確的,但需要哄着 TS 去檢查它。 例如,使用 console.log() 將調用包裝在 Playground 中會生成您想要的類型檢查。

TS 作為檢查器並不完美,因此在高度復雜的情況下它可能需要一些技巧才能檢測到“正確”的解決方案 - 這就是!

問題似乎更像是 Typescript 的限制。 我發現的一種解決方法,對我們來說是一個完整的解決方案,如下所示:

function myStyles<StyleVariants>(params: {
  baseStyles: AllowedStyles;
  styleVariantKeys: StyleVariants;
  styleVariants: StyleVariantsStructure;
}): StyleVariants {
  return params.styleVariantKeys;
}
  1. styleVariantsKey對象添加到myStyles函數參數中
  2. 從中推斷類型
  3. styleVariantsStyleVariantsStructure類型

這允許您按預期進行類型檢查,並允許您從styleVariantsKey返回推斷的類型。 但當然這意味着你必須有兩個相同的對象,在我們的例子中這不是什么大問題,因為我們實際上不需要myStyles返回嵌套的樣式對象,只需要變體名稱。 所以我們的函數調用看起來像這樣:

myStyles({
  baseStyles: {
    color: 'red',
    backgroundColor: 'red',
  },
  styleVariantKeys: {
    color: ["red"],
  },
  styleVariants: {
    color: {
      red: {
        color: 'red',
        backgroundColor: 'red',
      },
    },
  },
});

所以,我花在它上面的時間比我預期的要多,但我們來了。 如果您需要突出顯示錯別字,您應該基於 AllowedStyles 的 StyleVariants,例如:

type AllowedStyles = {
  color: 'red' | 'green';
  backgroundColor: 'red';
};

type StyleVariants = {
  [K in keyof AllowedStyles]?: AllowedStyles[K] | Partial<Record<AllowedStyles[K], Partial<AllowedStyles>>>
}

type StyleVariantsStructure = {
  baseStyles: AllowedStyles
  styleVariants: StyleVariants
}

function myStyles(params: StyleVariantsStructure):StyleVariants {
  return params.styleVariants;
}

StyleVariants 基於 AllowedStyles 結構和值,它包含 AllowedStyles 的所有屬性,但它們是可選的。 每個屬性的類型分別在 AllowedStyles 類型的屬性中提供,或者它是一個對象,其鍵是 AllowedStyles 中提供的每個類型的屬性,其類型又是 AllowedStyles,所有屬性都是可選的。 希望你能明白!

打字稿游樂場

暫無
暫無

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

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