如何从打字稿中的类中创建排除实例方法的类型?

时间:2019-04-02 16:36:06

标签: typescript typescript-generics

给出一个同时包含属性和方法的类,我想派生一个仅包含其属性的类型。

例如,如果我定义一个类如下:

class MyObject {

  constructor(public prop1: string, public prop2: number) {}

  instanceMethod() { ... }
}

我想要一个像这样的类型,例如MyObjectConstructor

type MyObjectConstructor = {
  prop1: string;
  prop2: string;
}

我知道我可以使用内置类型Pick并按名称手动选择我想要的键,但是我不想重复所有的键,而不必每次都更改它们我向班级添加了新属性。

是否可以定义仅返回打字稿中类属性的通用类型ConstructorType<T>

5 个答案:

答案 0 :(得分:1)

在阅读此issue时,我发现有人张贴了这种简洁的类型

type ExcludeMethods<T> = 
  Pick<T, { [K in keyof T]: T[K] extends (_: any) => any ? never : K }[keyof T]>;

请注意,此类型不会删除获取器和设置器。

答案 1 :(得分:0)

感谢这篇文章,我找到了一种排除与给定类型匹配的所有属性的方法:https://medium.com/dailyjs/typescript-create-a-condition-based-subset-types-9d902cea5b8c

我做了一些改编,但这是细节:

// 1 Transform the type to flag all the undesired keys as 'never'
type FlagExcludedType<Base, Type> = { [Key in keyof Base]: Base[Key] extends Type ? never : Key };

// 2 Get the keys that are not flagged as 'never'
type AllowedNames<Base, Type> = FlagExcludedType<Base, Type>[keyof Base];

// 3 Use this with a simple Pick to get the right interface, excluding the undesired type
type OmitType<Base, Type> = Pick<Base, AllowedNames<Base, Type>>;

// 4 Exclude the Function type to only get properties
type ConstructorType<T> = OmitType<T, Function>;

Try It

可能有一种更简单的方法,我尝试使用ConstructorParameters并定义构造函数签名,但没有结果。

答案 2 :(得分:0)

您尝试使用演员表吗?

const obj = <MyObject> {
  prop1: "abc",
  prop2: "xyz"
}

答案 3 :(得分:0)

  

给出一个既包含属性又包含方法的类,我想派生出一个Juste [sic]包含其属性的类型。

在您的示例中,您似乎希望结果仅包含字段(as opposed to only properties)。这是一种从对象或类实例中选择字段的类型。

type DataPropertyNames<T> = {
  [K in keyof T]: T[K] extends Function ? never : K;
}[keyof T];

type DataPropertiesOnly<T> = {
  [P in DataPropertyNames<T>]?: T[P] extends object ? DTO<T[P]> : T[P]
};

export type DTO<T> = DataPropertiesOnly<T>;

我使用了首字母缩写DTO来表示数据传输对象。

答案 4 :(得分:0)

export type DTO<T> = {
    [P in {
        [K in keyof T]: undefined extends T[K] ? never : T[K] extends (...args) => any ? never : K;
    }[keyof T]]: T[P] extends object ? DTO<T[P]> : T[P];
} &
    Partial<
        {
            [P in {
                [K in keyof T]: undefined extends T[K] ? K : never;
            }[keyof T]]: T[P] extends object ? DTO<T[P]> : T[P];
        }
    >;