Typescript Generics: 用于对象方法参数的类型安全泛型

huangapple go评论60阅读模式
英文:

Typescript Generics: type safe generics for parameters of a method of an object

问题

以下是您要翻译的内容:

我正在尝试使用泛型来从单个包装函数调用对象的函数以及其相应的参数。

这是我想要实现的内容:

class Class1 {
  method() {}
}

class Class2 {
  method(x: string) {}
}

class Class3 {
  method(x: number, y: string) {}
}

// 有效
wrapper(new Class1());
// 有效
wrapper(new Class2(), 'hello');
// 有效
wrapper(new Class3(), 10, 'hello');
// 无效
wrapper(new Class3(), '10', 'hello');

以下是我的尝试:

function wrapper<
  M extends { method: F },
  F extends (..._: any[]) => any,
  P extends Parameters<F>
>(m: M, ...p: P) {
  m.method(...p);
}

这段代码有效,但不提供参数 p 的类型安全性。我可以传递对于函数 m.method 无效的参数。

英文:

I am trying to use generics to invoke a function of an object with its respective parameters from a single wrapper function.

Here is what I am trying to achieve:

class Class1 {
  method() {}
}

class Class2 {
  method(x: string) {}
}

class Class 3 {
  method(x: number, y: string) {}
}

// valid
wrapper(new Class1());
// valid
wrapper(new Class2(), &#39;hello&#39;);
// valid
wrapper(new Class3(), 10, &#39;hello&#39;);
// invalid
wrapper(new Class3(), &#39;10&#39;, &#39;hello&#39;);

Here is my attempt:

function wrapper&lt;
  M extends { method: F },
  F extends (..._: any[]) =&gt; any,
  P extends Parameters&lt;F&gt;
&gt;(m: M, ...p: P) {
  m.method(...p);
}

This works, but does not provide type safety on the parameter p. I am able to pass parameters that are not valid for the function m.method.

答案1

得分: 1

Since the compiler doesn't have anywhere to infer F from (other type parameters are not used as inference sites), it defaults to its constraint of (...args: any[]) => any. You really only need 1 generic type parameter here:

function wrapper<
  F extends (...args: any[]) => any,
>(m: { method: F }, ...p: Parameters<F>) {
//     ^^^^^^^^^ inference point for F
  m.method(...p);
}
英文:

Since the compiler doesn't have anywhere to infer F from (other type parameters are not used as inference sites), it defaults to its constraint of (...args: any[]) =&gt; any. You really only need 1 generic type parameter here:

function wrapper&lt;
  F extends (...args: any[]) =&gt; any,
&gt;(m: { method: F }, ...p: Parameters&lt;F&gt;) {
//     ^^^^^^^^^ inference point for F
  m.method(...p);
}

Playground

huangapple
  • 本文由 发表于 2023年4月6日 23:27:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75951228.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定