是否可以在打字稿中重载对象函数属性?

eAb*_*Abi 9 typescript

我想知道是否有一种简单的方法可以在打字稿中重载对象的函数属性。例子:

interface Doable {
    do(s: number): number;
    do(s: string): string;
}

let obj: Doable = {
    do(s: number): number;
    do(s: string): string;
    do(s: number | string) {
        return s;
    }
}
Run Code Online (Sandbox Code Playgroud)

此处的编译器将引发错误,抱怨do属性重复。是否有另一种方法可以在不使用的情况下声明函数any

我已经知道这个实现会起作用。

let obj: Doable = {
    do(s: any) {
        return s;
    }
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*den 15

如果您需要在不依赖接口的情况下执行此操作,您可以通过在对象字面量范围内重载一个函数然后在字面量上设置它来完成此操作。

例子:

function myFunc(a : number) : number;
function myFunc(b : string, c : string) : boolean;
function myFunc(a : number | string, c? : string) : any{
  //function impl goes here
}

const myLiteral = {
   myFunc
};
Run Code Online (Sandbox Code Playgroud)

这样您就不必使用任何参数,并且可以使用具有不同数量参数的函数。(在我的示例中返回 any 的函数定义没有用作有效的函数签名之一;只有 impl 之前的前两个定义是。)

想法来自:https : //www.typescriptlang.org/docs/handbook/functions.html(滚动到底部)


Rya*_*ugh 10

您不需要在对象文字中声明重载签名。写就好了:

interface Doable {
    do(s: number): number;
    do(s: string): string;
}

let obj: Doable = {
    do(s: number | string): any {
        return 42;
        return '';
    }
}

obj(42); obj(''); // OK
Run Code Online (Sandbox Code Playgroud)

其中的返回值检查部分有点奇怪,因为从技术上讲,TypeScript 希望您返回number & string这实际上不会发生的事情,因此使用any作为返回类型是最简单的方法。

  • 这对于具有不同数量参数的重载是不正确的。同样,真正的重载返回正确的类型,具体取决于匹配的签名,而不是任何失去所有类型安全性的签名 (2认同)

for*_*d04 7

您可以结合其他答案中两个世界的优点:

interface Doable {
    foo(s: number): number;
    foo(s: string): string;
}

function fn(s: number): number;
function fn(s: string): string;
function fn(s: string | number): string | number {
    return Math.random() > 0.5 ? "foo" : 42
    // strong types for callee / function body:
    // e.g. `return true` causes error, as not assignable to string | number
}

let obj: Doable = { foo: fn }

// strong types for caller / consumer
obj.foo(42) // number
obj.foo("foo") // string
// obj.do(true) // error
Run Code Online (Sandbox Code Playgroud)

操场


Gre*_*ude 5

事实上,直接把它放在对象上是可以的!语法有点笨拙,但它有效:

let myLiteral = {
  myFunc: ((a : number | string, c? : string) => {
    // implementation goes here
  }) as {
    // overloads go here
    (a : number): number;
    (b : string, c : string): boolean;
  }
};
Run Code Online (Sandbox Code Playgroud)