网站搜索

基于输入的 TypeScript 返回类型


我有以下函数:

subtract(sub: number | CalendarWeek): T {
    if (typeof sub === 'number') {
        return new CalendarWeek(...); // Returns a CalendarWeek if sub is a number
    }

    return 1; // Return number if sub is CalendarWeek
}

问题是我需要定义类型 T,使其依赖于提供的 sub 类型。也就是说,如果 sub 是 CalendarWeek,则 T 是 number;如果 sub 是 number,则 T 是 CalendarWeek。

答案#1

处理这个问题的传统 TypeScript 方法是使用重载函数。在你的情况下,它可能是这样的:

subtract(sub: number): CalendarWeek;
subtract(sub: CalendarWeek): number;
subtract(sub: number | CalendarWeek): number | CalendarWeek {
  if (typeof sub === 'number') {
    return new CalendarWeek(...); // Returns a CalendarWeek if sub is a number
  }
  return 1; // Return number if sub is CalendarWeek
}

在 TypeScript 2.8 及以上版本中,你可以设想使用条件类型而不是重载来表示这一点,但这可能比你想要达到的更高级。

对于有兴趣的各方,这个解决方案看起来是这样的:

subtract<T extends number | CalendarWeek>(sub: T): T extends number ? CalendarWeek : number;
subtract(sub: number | CalendarWeek): number | CalendarWeek {
  if (typeof sub === 'number') {
    return new CalendarWeek(); // Returns a CalendarWeek if sub is a number
  }
  return 1; // Return number if sub is CalendarWeek
}

希望这有帮助。祝你好运!

答案#2

你可以使用多个重载来根据参数的类型返回特定类型

function subtract(sub: number): CalendarWeek
function subtract(sub: CalendarWeek): number
function subtract(sub: number | CalendarWeek): number | CalendarWeek {
    if (typeof sub === 'number') {
        return new CalendarWeek(); // Returns a CalendarWeek if sub is a number
    }

    return 1; // Return number if sub is CalendarWeek
}

或者我们可以使用条件类型来达到类似的效果:

function subtract<T extends number | CalendarWeek>(sub: T): T extends number ? number : CalendarWeek
function subtract(sub: number | CalendarWeek): number | CalendarWeek {
    if (typeof sub === 'number') {
        return new CalendarWeek(); // Returns a CalendarWeek if sub is a number
    }

    return 1; // Return number if sub is CalendarWeek
}