如何在TypeScript中指定任何可新建的类型?

0h4hbjxa  于 2022-12-27  发布在  TypeScript
关注(0)|答案(3)|浏览(162)

我试过了,但是不起作用。Foo只是一个测试。Bar才是真实的的尝试,它应该接收任何新的类型,但是Object的子类对于这个目的是无效的。

class A {

}
class B {
    public Foo(newable: typeof A):void {

    }
    public Bar(newable: typeof Object):void {

    }
}

var b = new B();
b.Foo(A);
b.Bar(A); // <- error here
hiz5n14c

hiz5n14c1#

可以使用{ new(...args: any[]): any; }来允许任何对象具有带任何参数的构造函数。

class A {

}

class B {
    public Foo(newable: typeof A):void {

    }

    public Bar(newable: { new(...args: any[]): any; }):void {

    }
}

var b = new B();
b.Foo(A);
b.Bar(A);  // no error
b.Bar({}); // error
wqsoz72f

wqsoz72f2#

如果只想强制某些新对象,可以指定构造函数的返回类型

interface Newable {
  errorConstructor: new(...args: any) => Error; // <- put here whatever Base Class you want
}
  • 等值 *
declare class AnyError extends Error { // <- put here whatever Base Class you want
  // constructor(...args: any) // you can reuse or override Base Class' contructor signature
}

interface Newable {
  errorConstructor: typeof AnyError;
}
  • 测试 *
class NotError {}
class MyError extends Error {}

const errorCreator1: Newable = {
  errorConstructor: NotError, // Type 'typeof NotError' is missing the following properties from type 'typeof AnyError': captureStackTrace, stackTraceLimitts
};

const errorCreator2: Newable = {
  errorConstructor: MyError, // OK
};
6psbrbz9

6psbrbz93#

使用TypeScript的Construct Signature功能,可以创建一个新函数。

/*
* Create a newable function
*/

type Vector2D = {
  x: number
  y: number
}

type Vector2DConstructor = {
  new(x: number, y: number): Vector2D
  (x:number, y: number): Vector2D
}

const Vector2D = function (this: Vector2D, x: number, y: number): Vector2D {
  if (x < 3) throw new Error('x cannot be smaller than 3')
  if (!new.target) {
    return {x, y}
  }
  this.x = x
  this.y = y
  return this
} as Vector2DConstructor // without type casting, it won't work

const a = new Vector2D(3, 3)
console.log(a)

你可以在操场上试试。
这样做有一些缺点:

  • 必须使用类型转换,这对于错误检查是不安全的。
  • 您必须确保Constructor类型的参数与函数的参数匹配。否则,将产生意外错误。

相关问题