【问题标题】:Why can't I add an overload in a derived interface?为什么我不能在派生接口中添加重载?
【发布时间】:2021-02-16 10:00:17
【问题描述】:

我正在尝试创建一个派生接口,为现有方法添加新的重载。但 TypeScript 不会让我这样做。

考虑以下允许添加两个numbers 的接口:

interface SimpleAdder {
  add(a: number, b: number): number;
}

假设我想创建一个派生接口——除了numbers——还允许添加bigints。我希望以下代码可以工作:

interface ExtendedAdder extends SimpleAdder {
  add(a: bigint, b: bigint): bigint;
}

此代码给出以下错误:

接口“ExtendedAdder”错误地扩展了接口“SimpleAdder”。 属性“添加”的类型不兼容。 类型 '(a: bigint, b: bigint) => bigint' 不可分配给类型 '(a: number, b: number) => number'。 参数“a”和“a”的类型不兼容。 类型“数字”不可分配给类型“bigint”。(2430)

TypeScript 似乎不明白我在尝试添加重载,而不是替换方法签名。

如果我明确地重复继承的重载,它确实有效。但这对我来说似乎是多余的(尤其是在更复杂的阅读世界场景中):

interface ExtendedAdder extends SimpleAdder {
  add(a: number, b: number): number; // Copied from SimpleAdder
  add(a: bigint, b: bigint): bigint;
}

我发现的另一个解决方法是将ExtendedAdder 定义为类型别名而不是接口。但是这种方法缺乏派生接口的清晰性:

type ExtendedAdder = SimpleAdder & {
  add(a: bigint, b: bigint): bigint;
}

编辑:我的实际代码与添加数字无关,而且我的实际函数签名更复杂。这个问题严格来说是关于通过派生接口向现有方法添加重载,而不是关于这个特定的用例。

【问题讨论】:

  • 这里catchts.com/math你可以找到一个例子
  • @captain-yossarian “加法器”用例只是说明派生接口中的重载问题的一个示例。我已经编辑了问题以澄清这一点。
  • 请检查是否有帮助typescriptlang.org/play?#code/…

标签: typescript interface


【解决方案1】:

这里有通用解决方案:

//https://stackoverflow.com/questions/50374908/transform-union-type-to-intersection-type/50375286#50375286
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
  k: infer I
) => void
  ? I
  : never;

type A = (a: number, b: number) => number;
type B = (a: bigint, b: bigint) => bigint;
type C = (a: number[], b: string, c: string[]) => 42

type Fn = (...args: any[]) => any;
type AllFn = [A, B, C]

type Overloading<T extends ReadonlyArray<Fn>> = UnionToIntersection<T[number]>

type OverloadingParams<T extends ReadonlyArray<Fn>> = Parameters<T[number]>

const x: Overloading<AllFn> = (...arg: OverloadingParams<AllFn>) => null as any;

const result1 = x(2n, 2n) // bigint
const result2 = x(2, 2)// number
const result3 = x([1, 2], 'sd', ['sdf']) //42
const result4 = x(1, 'sd', ['sdf']) //expected error
const result5 = x([1], 2n, ['sdf']) //expected error
const result6 = x([1], 2, ['sdf']) //expected error
const result7 = x(1, 2,2) //expected error

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-04
    • 2014-08-30
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-24
    相关资源
    最近更新 更多