【问题标题】:How to copy the structure of one generic type to another generic in TypeScript?如何将一种泛型类型的结构复制到 TypeScript 中的另一种泛型?
【发布时间】:2021-09-07 08:05:07
【问题描述】:

假设我们有以下输入类型:

interface Input {
    name: string;
    heightCm: number;
    dob: Date;
}

我想写一个函数,可以根据这个输入产生以下输出类型:

interface Output {
    name: boolean;
    heightCm: boolean;
    dob: boolean;
}

换句话说,一个复制输入结构并将该结构作为输出返回的函数,将所有值设置为布尔值。

函数签名看起来像这样:

interface GenericMap<T> {
    [key: string]: T;
}

type InputToOutput<In, Out extends GenericMap<boolean>> = (input: In) => Out;

如果Input属性的类型最初是字符串,则将该属性标记为true,否则标记为false

例如该函数将根据上面的Input 产生以下结果:

{
    name: true,
    heightCm: false,
    dob: false
}

但最重要的是,它需要是类型安全的,这样我才能在结果对象上接收智能感知。

帮助不胜感激!

【问题讨论】:

  • 我不确定您是否只是在寻找mapped types,或者您真的想要具有尽可能强类型的完整实现,例如this。该代码是否满足您的需求,还是您想要别的东西?

标签: javascript typescript typescript-generics


【解决方案1】:

我想你只是想要一个将每个属性的类型设置为布尔值的映射类型?

type GenericMap<T> = {
    [K in keyof T]: boolean
}

你会使用喜欢的:

interface Input {
    name: string;
    heightCm: number;
    dob: Date;
}

type Output = GenericMap<Input>
// Output is
// {
//    name: boolean;
//    heightCm: boolean;
//    dob: boolean;
// }

Playground


作为一个(潜在的)改进,您甚至可以检查此类型别名中的string 并返回truefalse,而不是boolean

type GenericMap<T> = {
    [K in keyof T]: T[K] extends string ? true : false
}

这会产生这种类型:

type Output = GenericMap<Input>
// {
//    name: true;
//    heightCm: false;
//    dob: false;
// }

【讨论】:

  • 您好,我收到一个错误,即在 GenericMap 中使用它时找不到名称“keyof”,如您所示。但是,这可行:type K&lt;T&gt; = keyof GenericMap&lt;T&gt;; 但是我仍然不能将其用作 GenericMap 的键签名。有任何想法吗?我在 Typescript @4.3
  • 问题是我使用interface 来定义GenericMap。它必须是 type 才能在密钥签名中使用“keyof”(无论出于何种原因)
【解决方案2】:

我已经实现了你想要的:

interface Input {
    name: string;
    heightCm: number;
    dob: Date;
}

type Out<In> = { [key in keyof In]: In[key] extends string ? true : false }
type InputToOutput<In> = (input: In) => Out<In>;
type Output = Out<Input>;

const clone: InputToOutput<Input> = input => output;

const input: Input = { name: 'foo', heightCm: 3, dob: new Date };

const output: Output = clone(input);

当悬停Output 类型时会给出以下输出:

const output: {
    name: true;
    heightCm: false;
    dob: false;
}

【讨论】:

    猜你喜欢
    • 2020-08-21
    • 2021-09-08
    • 1970-01-01
    • 2019-12-06
    • 2018-06-12
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多