【问题标题】:Remove properties of a type from another type从另一个类型中删除一个类型的属性
【发布时间】:2018-11-23 00:46:20
【问题描述】:

这个问题类似,但和Typescript 2.8: Remove properties in one type from another有点不同

我想创建一个函数,它接受一个类型,并返回一个不包含 Array 类型属性或其他复杂(嵌套)对象的新类型。

我假设条件类型是处理此问题的最佳(唯一?)方法?这如何实现?

【问题讨论】:

  • 您是否考虑过利用 Record 将所有复杂属性映射为 undefined 或 null 以及 Pick 那些两者都不是的属性?
  • 或者我会考虑只使用Array#reduce 并根据谓词函数动态填充对象。
  • 我只使用了 .NET 端口——这很棒,但也许这样的东西会有所帮助? github.com/loedeman/AutoMapper

标签: typescript typescript2.8 conditional-types


【解决方案1】:

您可以使用条件类型(用于挑选键)和Pick

创建一个仅保留原始类型(不包括数组和其他对象)的条件类型
type PrimitiveKeys<T> = {
    [P in keyof T]: Exclude<T[P], undefined> extends object ? never : P
}[keyof T];
type OnlyPrimitives<T> = Pick<T, PrimitiveKeys<T>>

interface Foo {
    n: number;
    s: string;
    arr: number[];
    complex: {
        n: number;
        s: string;
    }
} 

let d : OnlyPrimitives<Foo> // will be { n: number, s: string }

实际的函数实现应该很简单,只是迭代对象属性并排除object

function onlyPrimitives<T>(obj: T) : OnlyPrimitives<T>{
    let result: any = {};
    for (let prop in obj) {
        if (typeof obj[prop] !== 'object' && typeof obj[prop] !== 'function') {
            result[prop] = obj[prop]
        }
    }
    return result;
}

let foo = onlyPrimitives({ n: 10, s: "", arr: [] }) ;

编辑添加了对可选字段的正确处理。

【讨论】:

  • 这适用于您拥有的示例,但不适用于我定义的 DeepPartial 类型:ts export type DeepPartial&lt;T&gt; = { [P in keyof T]?: T[P] extends Array&lt;infer UArray&gt; ? Array&lt;DeepPartial&lt;UArray&gt;&gt; : T[P] extends ReadonlyArray&lt;infer UReadonlyArray&gt; ? ReadonlyArray&lt;DeepPartial&lt;UReadonlyArray&gt;&gt; : DeepPartial&lt;T[P]&gt; }; 用法示例,例如:pickPrimitives({} as DeepPartial&lt;Foo&gt;) 所以我目前正在调整类型看看我能不能找出问题所在并修复它
  • 实际上,它甚至不直接与 DeepPartial 类型有关,当类型在其类型域中具有 undefined 时,这将不起作用,例如当属性是可选的时。我猜这是有道理的,因为ComplexObject | undefined 的类型不一定是object 的类型。通过将[P in keyof T]: T[P] extends object ? never : P 更改为[P in keyof T]: Exclude&lt;T[P], undefined&gt; extends object ? never : P,我能够得到这个工作(据我所知)
  • @MikeHaas 是的,我没有使用可选字段进行测试...我会更新答案以包含您的更改
猜你喜欢
  • 1970-01-01
  • 2022-12-19
  • 2021-04-04
  • 1970-01-01
  • 2021-04-02
  • 1970-01-01
  • 2018-08-19
相关资源
最近更新 更多