根据TypeScript中的另一个属性值动态解析属性类型

时间:2017-01-17 19:39:06

标签: typescript

我有以下TypeScript界面​​:

customEvents
| where customDimensions['MyApp'] == "HelloWorld"

我想添加名为interface SelectProps { options: Option[]; value: string[]; onChange: (value: string[]) => void; } 的布尔值,它将改变其他属性的类型。

isMultiple

  • 强制执行isMultiple=true
  • 强制执行value:string[]

onChange: (value: string[]) => void;

  • 强制执行isMultiple=false
  • 强制执行value:string

是否可以根据一个属性的值动态设置其他属性的类型?

2 个答案:

答案 0 :(得分:13)

有点晚了,但我希望有人能帮助我这样的人。

可以使用受歧视的联合,也称为标记联合或代数数据类型来解决此问题。

interface MultipleSelectProps {
    isMultiple: true;
    options: string[];
    value: string[];
    onChange: (value: string[]) => void;
}

interface SingleSelectProps {
    isMultiple: false;
    options: string[];
    value: string;
    onChange: (value: string) => void;
}

type SelectProps = MultipleSelectProps | SingleSelectProps;

用法示例:

function Select(props: SelectProps) {
    if (props.isMultiple) {
        const { id, onChange } = props;
        onChange(id);
    } else if (props.isMultiple === false) {
        const { id, onChange } = props;
        onChange(id);
    }
}
  

注意:当isMultipleundefinednull时,无法推断SelectProps的具体类型。在这些情况下,有必要进行严格的比较isMultiple === false

来源:https://blog.mariusschulz.com/2016/11/03/typescript-2-0-tagged-union-types

答案 1 :(得分:1)

不,你不能这样做,但这里有两个选择

(1)使用valueonChange的联合类型:

interface SelectProps {
    options: Option[];
    isMultiple: boolean;
    value: string | string[];
    onChange: (value: string | string[]) => void;
}

(2)对两种情况使用两种不同的接口:

interface SelectProps {
    options: Option[];
    isMultiple: boolean;
}

interface SingleSelectProps extends SelectProps {
    value: string;
    onChange: (value: string) => void;
}

interface MultipleSelectProps extends SelectProps {
    value: string[];
    onChange: (value: string[]) => void;
}

function isSingle(props: SelectProps): props is SingleSelectProps {
    return !props.isMultiple;
}

function isMultiple(props: SelectProps): props is MultipleSelectProps {
    return props.isMultiple;
}

code in playground