Typescript通用约束,其中一种类型的属性取决于另一种类型

时间:2019-12-28 18:48:16

标签: typescript typescript-generics

我正在尝试创建一个正在使用的函数,如下所示:

Foo(Number, (aNum: number) => {});

我正在尝试使用通用名称,其中第二个参数中的回调参数必须与第一个参数的类型相同。

第一个类型很简单:

function getObjectConstructor() {
  return Object.prototype.constructor;
}

type Type = ReturnType<typeof getObjectConstructor>

function thing(a: Type): void {
  console.log(a.name);
}

thing(Number);

但是,我在创建此依赖项方面有些困惑,基本上,我试图从Type中读取name属性值,并从第二种类型中获取名称,然后查看它们是否匹配。像这样:

interface HasName {
  name: string;
}

interface HasConstructor {
  constructor: HasName
}

function AreSameName<T extends Type, U extends HasConstructor>(a: T, b: U) {
  return a.name === b.constructor.name
}

但是作为一般约束。我不确定是否可行,我是Typescript的新手。

1 个答案:

答案 0 :(得分:1)

函数的name属性的类型为string,因此在编译时没有字符串文字。您将无法基于name的值引起编译错误。

作为一种可能的选择,您可以将第二个参数的类型限制为第一个参数的InstanceType。 ({InstanceType<T>是在new上使用T运算符时得到的类型。)请参见this example

declare function test<T extends new (...args: any[]) => any>(
    ctor: T, value: InstanceType<T>
): any;

test(Number, 123);
test(Number, "123"); // Error: string is not assignable to number.
test(String, 123); // Error: number is not assignable to string.
test(String, "123");

// Object function returns "any", so anything goes...
test(Object, 123);

class A {
  private x: string = "hello";
}

class B {
  private y: number = 123;
}

test(A, "123"); // Error: string is not assignable to A.
test(B, new A()); // Error: A is not assignable to B.
test(B, new B());