Typescript可选泛型类型

Mar*_*ius 40 generics typescript

我有以下日志记录方法:

  private logData<T, S>(operation: string, responseData: T, requestData?: S) {
    this.logger.log(operation + ' ' + this.url);
    if (requestData) {
      this.logger.log('SENT');
      this.logger.log(requestData);
    }
    this.logger.log('RECEIVED');
    this.logger.log(responseData);
    return responseData;
  }
Run Code Online (Sandbox Code Playgroud)

requestData是可选的,我希望能够在不发送方法时调用logData而不必指定S类型requestData:而不是:this.logData<T, any>('GET', data),我想调用this.logData<T>('GET', data).有没有办法实现这个目标?

kim*_*ula 88

从TypeScript 2.3开始,您可以使用通用参数默认值.

private logData<T, S = {}>(operation: string, responseData: T, requestData?: S) {
  // your implementation here
}
Run Code Online (Sandbox Code Playgroud)

  • 不要使用“{}”作为类型。`{}` 实际上意味着“任何非空值”。eslint(@typescript-eslint/禁止类型) (9认同)
  • `S = any` 应该允许任何类型 (7认同)
  • 好奇使用`S = never'是否会在使用可选参数时强制指定类型。 (5认同)

Sir*_*lam 38

TS 2020 年更新:Givingvoid将使泛型类型成为可选。

type SomeType<T = void> = OtherType<T>;
Run Code Online (Sandbox Code Playgroud)

上面给出了作为对象的默认值的答案使其成为可选但仍为其赋予价值。


默认类型值的示例是{}

type BaseFunctionType<T1, T2> = (a:T1, b:T2) => void;

type FunctionType<T = {}> = BaseFunctionType<{name: string}, T>

const someFunction:FunctionType = (a) => {

}

someFunction({ name: "Siraj" });
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
// Expected 2 arguments, but got 1.(2554)
Run Code Online (Sandbox Code Playgroud)

游乐场链接


具有默认泛型类型值的示例是 void

type BaseFunctionType<T1, T2> = (a:T1, b:T2) => void;

type FunctionType<T = void> = BaseFunctionType<{name: string}, T>

const someFunction:FunctionType = (a) => {

}

someFunction({ name: "Siraj" })
Run Code Online (Sandbox Code Playgroud)

这是关于使泛型可选的很好的读物。

Typescript 中的可选泛型类型

游乐场链接

  • 可爱的,谢谢。这是在哪里记录的(官方)? (2认同)

pan*_*ter 14

如果您正在类型/接口声明中寻找可选的泛型类型,这可能会有所帮助。

(来寻找这个,只找到了处理通用函数声明的答案。Siraj的答案让我走上了正轨。)

type ResponseWithMessage = {
  message: string;
};

interface ResponseWithData<T> extends ResponseWithMessage {
  data: T;
}

export type ResponseObject<T = void> = T extends void
  ? ResponseWithMessage
  : ResponseWithData<T>;
Run Code Online (Sandbox Code Playgroud)


小智 11

根据TypeScript 2.2(你可以在TS Playground中尝试它),调用this.logData("GET", data)(带有data类型T)可以成功推断出来this.logData<T, {}>("GET", data).

如果推断因您使用的TS版本而失败,则可以应用David Bohunek建议的过载.无论如何,确保第二个签名在声明之前然后定义,否则它将不参与可用的重载.

// Declarations
private logData<T>(operation: string, responseData: T);
private logData<T, S>(operation: string, responseData: T, requestData?: S);
// Definition
private logData<T, S>(operation: string, responseData: T, requestData?: S) {
    // Body
}
Run Code Online (Sandbox Code Playgroud)

  • 在 TS 3.8.3 上,它被推断为“未知”而不是“{}” (5认同)