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

Typescript Generic Constraint where the property of one type depends on the other

我正在尝试创建一个在使用中看起来像这样的函数:

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);

但是我在创建这种依赖关系时有点卡住了,基本上我试图从类型中读取名称 属性 值并从第二种类型中获取名称并查看它们是否匹配。像这样:

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 的新手。

函数的 name 属性 类型为 string,因此在编译时没有字符串文字。您将无法根据 name.

的值导致编译错误

作为一种可能的替代方法,您可以将第二个参数的类型限制为第一个参数的 InstanceType。 (InstanceType<T> 是在 T 上使用 new 运算符时得到的类型。)参见 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());