简体   繁体   English

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

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

I'm attempting to create a function that in use will look like this:我正在尝试创建一个正在使用的函数,如下所示:

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

I am attempting to make this generic where the parameter of the callback in the second argument must be of the same type as the first.我试图使这个通用,其中第二个参数中的回调参数必须与第一个参数类型相同。

The type in the first was easy:第一个类型很简单:

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

type Type = ReturnType<typeof getObjectConstructor>

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

thing(Number);

However I am a little stuck on creating this dependency, basically I'm trying to read the name property value from Type and get the name from the second type and see if they match.但是,我在创建此依赖项上有些困难,基本上我试图从 Type 读取 name 属性值并从第二个类型获取名称,看看它们是否匹配。 Something like this:像这样的东西:

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
}

But as a generic constraint.但作为通用约束。 I'm not sure if this is possible, I'm new to Typescript.我不确定这是否可行,我是 Typescript 的新手。

The name property of a function is typed as a string , so you don't have a string literal at compile time.函数的name属性被键入为string ,因此在编译时您没有字符串文字。 You won't be able to cause compile errors based on the value of name .您将无法根据name的值导致编译错误。

As a possible alternative, you may be able to constraint the type of the second parameter to the InstanceType of the first parameter.作为一种可能的替代方法,您可以将第二个参数的类型限制为第一个参数的InstanceType ( InstanceType<T> is the type you get when using the new operator on T .) See this example : InstanceType<T>是在T上使用new运算符时获得的类型。)请参阅此示例

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM