gpt4 book ai didi

javascript - typescript 中的方法参数和返回类型覆盖

转载 作者:搜寻专家 更新时间:2023-10-30 21:30:13 24 4
gpt4 key购买 nike

我不想描述抽象类中的抽象方法,它可以接受numberstring 并返回数字或字符串;我使用 | 符号来告诉方法它的参数和返回类型可能因字符串和数字而异。
然后我创建了两个类 bc ,它们是从抽象类 a 扩展而来的,并试图覆盖方法 test() 没有参数和返回类型变化。
接下来,我声明变量 x 类型可能类似于 bc 类,我正在创建其中之一的实例类取决于随机语句。
最后,我试图调用 test() 方法,但 TS 编译器给我如下所述的错误。

abstract class a {
abstract test(x: string | number): string | number;
}

class b extends a {
test(x: number): number {
return x;
}
}


class c extends a {
test(x: string): string {
return x;
}
}

let x: b | c;


if (Math.random() > 0.5) {
x = new b()
} else {
x = new c()
};

x.test(1)

这是 TS 编译器的错误:

无法调用类型缺少调用签名的表达式。输入 '((x: 数字) => 数字) | ((x: string) => string)' 没有兼容的调用签名。
(属性)测试:((x:数字)=>数字)| ((x: 字符串) => 字符串)

也许我使用了错误的方法或者我误解了 TS 文档,如果是的话 - 你能指出我实现目标的更好方法吗?
抱歉,类名不佳且没有任何“ fiddle ”-我找不到任何突出显示 TS 编译器错误的 js Playground 网站,所以我推荐官方 TS Playground

最佳答案

当您在 if block 中创建类的实例时, typescript 编译器无法确定 x 的类型。没关系,但问题是您随后尝试使用数字调用测试函数,而这只有在类型为 b 时才有可能。因为编译器认为 x 有可能是 c 类型,所以你会得到一个错误。

您需要向编译器保证,当您调用测试时,您调用的函数将始终匹配提供的参数。

您可以:

  1. 更改调用签名,以便两者都接受任何类型,这样编译器就不会关心调用哪个方法:

    class b extends a {
    test(x: any) {
    return x;
    }
    }

    class c extends a {
    test(x : any) {
    return x;
    }
    }
  2. 在 if block 中调用方法:

    if (Math.random() > 0.5) {
    x = new b();
    x.test(1);
    } else {
    x = new c();
    x.test('1');
    }
  3. 类型保护你的方法调用:

    if (x instanceof b)
    x.test(1);
    else if(x instanceof c)
    x.test('1');

查看联合类型和类型保护手册:https://www.typescriptlang.org/docs/handbook/advanced-types.html#union-types .

编辑:给你的建议是在方法本身中完成类型检查,这样你就不必在每次调用时都输入类型。这样做的缺点是可以使用不正确的参数调用方法,而不会收到编译器的警告。这是一个看起来如何的示例:

abstract class a {
protected abstract internal(x: any): any;

public test(x: string | number): string | number {
return this.internal(x);
}
}

class b extends a {
protected internal(x) {
if (typeof x === "number")
return x;
else
throw new Error("Invalid argument");
}
}


class c extends a {
protected internal(x) {
if (typeof x === "string")
return x;
else
throw new Error("Invalid argument");
}
}

let x: b | c;


if (Math.random() > 0.5) {
x = new b();
} else {
x = new c();
}

x.test(1);

关于javascript - typescript 中的方法参数和返回类型覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41055565/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com