簡體   English   中英

制作動態可調用 typescript 接口屬性

[英]Making a Dynamic callable typescript interface property

這是調色板的一部分,我在這里使用IPalette界面:

{
  warningColor: '#FFCA28',
  smallWidgetBackground: ["rgba(255,255,255,0.15)", "rgba(255,255,255,0)"],
  grayColorAlpha: (opacity: number) => `rgba(200, 209, 232, ${opacity})`,
  welcome: {
    primaryText: "#fff",
    primaryTextAlpha: (alpha = 1) => `rgba(255,255,255,${alpha})`,
  },
}

問題是我想創建一個具有動態屬性的接口,無論是作為字符串的鍵,還是鍵也是可調用的。

考慮這個例子:



type RGBA = `rgba(${number}, ${number}, ${number}, ${number})`

type Alpha = (opacity: number) => RGBA

type KeysHex = `${string}Color` | `${string}Text`

interface Data {
  [color: KeysHex]: `#${string}`
  [alpha: `${string}Alpha`]: Alpha
}

const foo: Data = {
  criticalColor: '2' // expected error
}

const bar: Data = {
  criticalColor: '#2' // ok, there is a limitation in TS
}

const baz: Data = {
  criticalColorAlpha: (opacity: number) => `rgba(1, 1, 1, ${opacity})` // ok
}

const baz2: Data = {
  criticalColorAlpha: (opacity: number) => `rgba(1, 1, 1, x)` // expected error
}

操場

我注意到,如果這是一種方法,則使用Alpha后綴;如果是 HEX 顏色,則使用ColorText 這就是為什么我決定為Data接口使用兩個不同的鍵。

您可以為RGBA使用 stonger 類型,但有一個限制。 請看我的文章這個答案。

關於 HEX colors 的相同故事。請參閱本文

請提供所有場景或限制,我會盡力為您提供最安全的類型。

謝謝

更新您在評論中使用的語法:

  [key in AdditionalKeysHex]:`#${string}`|string[];

是錯的。 您只能在映射類型中使用in運算符。 為了實現所需的行為,我認為應該拆分Data接口。

請查看DataResult類型:

type RGBA = `rgba(${number}, ${number}, ${number}, ${number})`

type Alpha = (opacity: number) => RGBA

type KeysHex = `${string}Color` | `${string}Text` | `${string}Icon` | `${string}Background`;

const arr = ['white', 'darkGrayBlue', 'secondDarkGrayBlue', 'thirdDarkGrayBlue', 'darkDullBlue', 'secondDarkDullBlue', 'lightGrayBlue', 'secondLightGrayBlue', 'thirdLightGrayBlue', 'fourthLightGrayBlue', 'fifthLighGrayBlue', 'lightGrayNavy', 'paleNavy', 'brightBlue']

type AdditionalKeysHex = 'white' | 'darkGrayBlue' | 'secondDarkGrayBlue' | 'thirdDarkGrayBlue' | 'darkDullBlue' | 'secondDarkDullBlue' | 'lightGrayBlue' | 'secondLightGrayBlue' | 'thirdLightGrayBlue' | 'fourthLightGrayBlue' | 'fifthLighGrayBlue' | 'lightGrayNavy' | 'paleNavy' | 'brightBlue';

interface IWelcome {
  [color: KeysHex]: `#${string}` | string[];
  [alpha: `${string}Alpha`]: Alpha;
}


type WithKey = {
  [key in AdditionalKeysHex]: `#${string}` | string[];

}

interface Data {
  [color: KeysHex]: `#${string}` | string[];
  [alpha: `${string}Alpha`]: Alpha;
  welcome: IWelcome;
}

type DataResult = WithKey & Data

const Palette: DataResult = {
  primaryText: "#58585B",
  secondaryText: "#39393B",
  secondaryIcon: "#C8D1E8",
  tertiaryText: "#8F8E94",
  smallWidgetBackground: ["rgba(255,255,255,0.15)", "rgba(255,255,255,0)"],
  grayColorAlpha: (opacity: number) => `rgba(200, 209, 232, ${opacity})`,
  primaryTextAlpha: (opacity: number = 1) => `rgba(255, 255, 255, ${opacity})`,
  welcome: {
    primaryText: "#fff",
    primaryTextAlpha: (opacity: number = 1) => `rgba(255, 255, 255, ${opacity})`,
    secondaryText: "#C8D1E8",
    loaderColor: "#fff",
  },
  white: '#FFFFFF',
  darkGrayBlue: '#363C52',
};


操場

您可以刪除特定的鍵:

export type AlphaColorProcessing = (opacity: number) => string;

export interface Styles {
  [key: string]: string | AlphaColorProcessing;
}

暫無
暫無

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

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