Typescript - 从接口实现匿名对象

Typescript - Implementation of an anonymous object from an interface

我是 Typescript 的新手,我在接口实现方面遇到了一些麻烦。

我的界面(来自 d3.js 类型):

export interface AxisScale<Domain> {
    (x: Domain): number | undefined;
    domain(): Domain[];
    range(): number[];
    copy(): this;
    bandwidth?(): number;
    // TODO: Reconsider the below, note that the compiler does not differentiate the overloads w.r.t. optionality
    // ticks?(count?: number): Domain[];
    // ticks?(count?: AxisTimeInterval): Date[];
    // tickFormat?(count?: number, specifier?: string): ((d: number) => string);
    // tickFormat?(count?: number | AxisTimeInterval, specifier?: string): ((d: Date) => string);
}

这就是我尝试实现接口的方式:

export class Axis implements AxisScale<number> {

    domain(): (number)[] {
        return [5];
    }

    range(): number[] {
        return [5, 10]
    }

    copy(): this {
        return this;
    }

    bandwidth?(): number {
        return d3.scaleBand().align();
    }

    side: 't' | 'b' | 'l' | 'r';
    color: string = "#000000";
    padding: number;
    margin: Margin;
}

当我保存文件时出现此错误:

Type 'Axis' provides no match for the signature '(x: number): number'.

如何在我的 class 中实现匿名对象 ((x: Domain): number | undefined;)?

AxisScale 接口定义了具有附加属性的函数类型,因此:

const AxisFunction: AxisScale<number> = (x: Domain) => {
  // ... content of function
}

AxisFunction.domain = (): number[] => {
  return [5];
}

AxisFunction.range = (): number[] => {
  return [5, 10]
}

AxisFunction.copy = (): AxisScale<number> => {
  return this;
}

AxisFunction.bandwidth = (): number => {
  return d3.scaleBand().align();
}

(x: Domain): number | undefined; 描述了一个函数签名。 class 无法实现包含索引签名的接口,只有函数可以:

export interface AxisScale<Domain> {
  (x: Domain): number | undefined;
  domain(): Domain[];
  range(): number[];
  copy(): this;
  bandwidth?(): number;
}

const CreateAxis = function (): AxisScale<number> {
  function Axis(this: typeof Axis, x: number): number {

    return 0
  }
  Axis.domain = function (): number[] {
    return [5];
  }

  Axis.range = function (): number[] {
    return [5, 10]
  }

  Axis.copy = function <T>(this: T): T {
    return this;
  }
  //   side: 't' | 'b' | 'l' | 'r';
  Axis.color= "#000000";
  Axis.padding = 0

  return Axis;
};

let axis = CreateAxis();
axis(10)
axis.domain()

Playground Link