【问题标题】:bi-directional conditional type mapping双向条件类型映射
【发布时间】:2022-01-13 00:27:51
【问题描述】:

我将对象的“数据类型”映射到“模式”类型。

当属性数据类型 == boolean 时,映射到“BooleanComponents”类型

下面的代码完成了这个:

type YesNoComponent = {
    type: 'yes-no'
}

type CheckboxComponent = {
    type: 'checkbox'
}

type TextComponent = {
    type: 'text'
}

type BooleanComponents = YesNoComponent | CheckboxComponent;
type StringComponents = TextComponent;

// this maps the Schema Data "type" to a "line type"
type TypeToComponent<T> = T extends string ? StringComponents :
    T extends boolean ? BooleanComponents :
    unknown;

type DataTypeToComponentSchema<T> = {
    [key in keyof T] : TypeToComponent<T[key]>
}

type FooDataType = {
  foo: string;
  bar: boolean;
}

type FooComponentType = DataTypeToComponentSchema<FooDataType>

//  type ComponentType = {
//    foo: StringComponents;
//    bar: BooleanComponents;
//  }

ts-playgroud link

但是,我还需要将“组件类型”映射回“数据类型”。

我可以做和以前一样的事情,只是相反:

type ComponentTypeToDataType<T> = T extends StringComponents ? string:
    T extends BooleanComponents ? boolean:
    unknown;

type FooPropertyDataType = ComponentTypeToDataType<CheckboxComponent>
// boolean

但这并不理想。

我想知道是否有一些方法或技巧可以在支持双向映射的两个类型集之间定义单一“关系”?

【问题讨论】:

  • 我刚刚使用“元组类型”进行了测试,至少可以将它们配对在一起......仍然感觉可能有更好的方法来管理这个。也许ts-toolbelt 有什么可以帮助清理的?

标签: typescript mapped-types conditional-types


【解决方案1】:

我最终使用了a type "Switch" statement 并添加了一个“反向开关”来反转映射:

type SwitchInverse<T, Conditions extends Array<[any, any]>> = 
      List.Head<Conditions> extends never
        ? never
        : T extends List.Head<Conditions>[1]
          ? List.Head<Conditions>[0]
          : SwitchInverse<T, List.Tail<Conditions>>;

我可以在一个地方管理所有映射:

type TypeComponentMappings<S> = [
    [boolean, YesNoComponent | CheckboxComponent],
    [string, TextComponent | SelectComponent],
    //...
];
export type AllComponents<S> = TypeComponentMappings<S>[number][1];

这使用了“递归类型”,所以我们将看看它的表现如何。

仍然认为可能有一种“更清洁的方式”来做到这一点......

【讨论】:

    猜你喜欢
    • 2019-03-21
    • 1970-01-01
    • 2019-04-06
    • 2016-04-19
    • 2020-05-10
    • 2022-08-18
    • 2020-10-08
    • 1970-01-01
    • 2010-11-14
    相关资源
    最近更新 更多