使用 Typescript 参数<>具有通用功能的实用程序类型

问题描述 投票:0回答:1

我有一堂课看起来像这样

class MyTestClass {
  getValue<T>(group: string, defaultVal: T): T {}
}

并且我尝试使用参数值来使此类的单元测试变得更容易(稍微做作来表达我的观点)


const argList1: Parameters<MyTestClass['getValue']> = ['group_1', 123];

const service = new MyTestClass();

const testValue1 = service.getValue<number>(...argList1);

最后一行出现以下错误

Argument of type 'unknown' is not assignable to parameter of type 'number'.ts(2345)

此跟踪,因为 T 未在

Parameters<>
定义中定义。

有办法做到这一点吗?感觉我已经在每个可能的位置尝试了尖括号,但没有任何效果。

我知道我可以在调用返回未定义的函数时不定义 T,但随后我必须手动转换它,它看起来很混乱。

typescript generics
1个回答
0
投票

问题

Parameters 将 getValue 的参数类型捕获为元组,但它不知道 T 的类型,因为它是泛型参数。因此,TypeScript 在使用参数时将 T 视为未知,因为它无法在没有显式类型信息的情况下推断 T。

这意味着你必须帮助打字稿在这里推断出正确的类型。 正如您所提到的,您可以通过手动转换参数类型来做到这一点。

解决技巧

class MyTestClass {
  getValue<T>(group: string, defaultVal: T): T {
    // Assume some logic here that returns T
    return defaultVal;
  }
}

// Wrapper function to call getValue with inferred types
function callGetValueWithInference<T>(
  instance: MyTestClass,
  ...args: Parameters<MyTestClass['getValue']>
): T {
  // TypeScript infers T based on the type of args[1]
  return instance.getValue(...args);
}

// Usage
const service = new MyTestClass();
const argList1: Parameters<MyTestClass['getValue']> = ['group_1', 123];

// TypeScript now correctly infers T as number based on argList1[1]
const testValue1 = callGetValueWithInference(service, ...argList1);
console.log(testValue1); // Outputs: 123

它是如何工作的

原始代码:

  • getValue 指定 T 应该是数字。
  • Parameters 返回一个元组类型 [string, 未知]因为 TypeScript 在提取时无法推断出 T 是什么 参数。泛型类型 T 在这种情况下并不固定,因此它 默认为未知。
  • 当您将 argList1 展开到 service.getValue(...argList1) 中时, argList1[1] 的类型未知,与预期不符 number 类型,导致 TypeScript 错误。

包装功能:

  • 辅助函数 callGetValueWithInference 没有显式地 调用 getValue 时提供类型 T。
  • 相反,它让 TypeScript 根据 args[1] 的类型推断 T (在本例中为 123)。由于 123 是一个数字,TypeScript 会推断 T 为数字。
  • 辅助函数之所以有效,是因为泛型类型 T 是在以下位置推断出来的: 函数被调用的点 (callGetValueWithInference(service, ...argList1)) 根据实际情况 值 (123) 传入 argList1。

© www.soinside.com 2019 - 2024. All rights reserved.