从类创建派生类型,但省略构造函数(打字稿)

时间:2019-10-25 16:45:30

标签: javascript typescript derived-types

我有一个这样定义的接口和类:

interface Foo {
  constructor: typeof Foo;
}

class Foo {
  static bar = 'bar';

  constructor(data: Partial<Foo>) {
    Object.assign(this, data);
  }

  someMethod() {
    return this.constructor.bar;
  }

  prop1: string;
  prop2: number;
}

接口是必需的,因此必须严格键入this.constructor。但是,这破坏了我将普通对象传递给类构造函数的能力:

const foo = new Foo({ prop1: 'asdf', prop2: 1234 });

// Argument of type '{ prop1: string; prop2: number; }' is not assignable to parameter of type 'Partial<Foo>'.
//  Types of property 'constructor' are incompatible.
//    Type 'Function' is not assignable to type 'typeof Foo'.
//      Type 'Function' provides no match for the signature 'new (data: Partial<Foo>): Foo'.

我了解错误消息,但是我不知道如何解决。有什么办法可以让我传递普通对象的Partial<Foo>吗?这是一个游乐场:

Playground

3 个答案:

答案 0 :(得分:1)

最终我找到了我所需的答案:

how to remove properties via mapped type in TypeScript

该答案中的代码创建一个包含 only 方法的派生类型。我需要做相反的事情。以下NonMethods<T>助手将创建一个派生类型,并删除所有方法。

type NonMethodKeys<T> = ({[P in keyof T]: T[P] extends Function ? never : P })[keyof T];  
type NonMethods<T> = Pick<T, JustMethodKeys<T>>; 

Here's the Playground

答案 1 :(得分:1)

这是实际的类型,它从一个类创建一个派生类型,而该类省略了构造函数(如问题标题中所示)并保留了常规方法:

type NonConstructorKeys<T> = ({[P in keyof T]: T[P] extends new () => any ? never : P })[keyof T];
type NonConstructor<T> = Pick<T, NonConstructorKeys<T>>;

与问题中的Foo一起使用:

type FooNonConstructorKeys = NonConstructorKeys<Foo>; // "prop1" | "prop2" | "someMethod"
type FooNonConstructor = NonConstructor<Foo>;

答案 2 :(得分:0)

看起来您想要定义一个接口然后使用它,然后必须在接口本身而不是类中定义属性。

interface Foo {
  prop1: string; // define your properties here
  prop2: number;
}

class Foo {
  static bar = 'bar';

  constructor(data: Partial<Foo>) {
    Object.assign(this, data);
  }

  someMethod() {
    return Foo.bar; // notice how I access static variables now
  }

}

const foo = new Foo({ prop1: 'asdf', prop2: 1234 });

Playground