首页 > 解决方案 > 从交叉路口类型中选择?(TS)

问题描述

我对 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),

标签: typescripttypescript-typingstypescript-generics

解决方案


添加这些声明以使代码编译:

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

为了使您的调用pick()类型安全,您可以合并ColorsPalette通过对象传播之类的方法:

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

之所以有效,是因为{...Colors, ...Palette}被视为类型ColorType & PaletteType,其键为keyof ColorType | keyof PaletteType

或者,您可以将用户定义的类型保护缩小props.backgroundColor到调用之前keyof ColorType或之前:keyof PaletteTypepick()

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],但我想这取决于你。

希望有帮助;祝你好运!


推荐阅读