Выбрать из типа пересечения?(TS), - PullRequest
0 голосов
/ 21 мая 2019

Я довольно новичок в TS и написал функцию выбора, но мне сложно выбрать тип пересечения:

type PaletteType = {
   black: string,
   white: string
}

type ColorType = {
   primaryColor: string,
   labelText: string,
}

type Props = {
   ...,
   backgroundColor: keyof ColorType | keyof PaletteType // (or would keyof (ColorType & PaletteType) would be better?
}

// Some general pick funtion
function pick<T extends { [key: string]: any }, K extends keyof T>(object: T, key?: K) {
    if (key) { return object[key] }
    return undefined
}

pick(Colors, props.backgroundColor) // error -> black | white not assignable to Colors

Я вполне уверен, что мое «решение» является неправильным:

backgroundColor: pick(Palette as typeof Palette & typeof Color, props.bg) || pick(Color as typeof Palette & typeof Color, props.bg),

1 Ответ

1 голос
/ 21 мая 2019

Добавление этих объявлений для компиляции кода:

declare const Colors: ColorType;
declare const Palette: PaletteType;
declare const props: Props;

Чтобы сделать вызов типа pick() безопасным, вы можете объединить Colors и Palette с помощью чего-то похожего на распространение объекта:

pick({ ...Colors, ...Palette }, props.backgroundColor); // okay

Это работает, потому что {...Colors, ...Palette} относится к типу ColorType & PaletteType, чьи ключи keyof ColorType | keyof PaletteType.

Или вы можете сделать определяемым пользователемнаберите guard , чтобы сузить props.backgroundColor до keyof ColorType или keyof PaletteType перед вызовом pick():

const hasKey = <T extends object>(obj: T, key: keyof any): key is keyof T => key in obj;

hasKey(Colors, props.backgroundColor) ? 
  pick(Colors, props.backgroundColor) : 
  pick(Palette, props.backgroundColor); // okay

Первый, вероятно, аккуратнее.

Кстати, я не уверен, что pick(o,k) покупает у вас всего за o[k], но я думаю, это зависит от вас.

Надеюсь, это поможет;удачи!

...