打字稿覆盖无效的抽象方法return

Typescript overriding abstract method which is void return

abstract class Base{
    abstract sayHello(): void;
}

class Child extends Base{
    sayHello() {
        return 123;
    }
}

抽象方法的 return 类型是 void 但我可以用数字类型 return 来实现它。 我没有从编译器中获取任何错误。 Typescript 有这种错误吗?

TS Spec

The Void type, referenced by the void keyword, represents the absence of a value and is used as the return type of functions with no return value.

Ryan Cavanaugh 领导 TS 开发:

The return value of a function reference whose return type is void can be anything because it's legal for a non-void-returning function to be aliased by a void-returning type.

所以事情是关于 type 的函数 returns void,可以接受(被分配)一个 value 的函数 returns 任何东西。

type ReturnVoid = () => void

const foo: ReturnVoid = () => 42  // all good

此行为在 Assignment Compatibility 部分

中进行了说明

M is a non-specialized call or construct signature and S has an apparent call or construct signature N where, [...] the result type of M is Void, or the result type of N is assignable to that of M

参考文献:

  1. https://github.com/Microsoft/TypeScript/wiki/FAQ#why-are-functions-returning-non-void-assignable-to-function-returning-void
  2. https://github.com/microsoft/TypeScript/issues/21674

这背后的原因是因为打字稿中的类型系统是在结构类型系统上工作的。类型的概念有点像 "contracts" ,其中设置规则以说明某些类型与某些类型兼容。如果合同被破坏,编译器只会出错。 例如:

abstract class Base{
    abstract sayHello(): void;
}

class Child extends Base{
    sayHello(): number {
        return 123;
    }
}

这是有效的,因为即使我们的方法 return 在我们实现它时的编号,所有使用 sayHello() 并期望它为 return 的东西都没有副作用,没有合同正在被打破。这仅仅是因为 Microsft 在打字稿中设置了一条规则,说 void return 类型与 number return 类型兼容。原因正如我之前所说,它没有副作用,所有期望 sayHello() 到 return void 的东西都应该按预期工作。

另一方面,如果我这样做:

abstract class Base{
    abstract sayHello(): number;
}

class Child extends Base{
    sayHello(): void {
        return;
    }
}

这会出错,因为现在所有使用 sayHello() 并期望它是数字的东西都会受到影响,类型约定已被破坏,从而导致编译器错误。

您可以将此视为类型系统中的一个灵活性特征,以权衡意外的类型等价性。

在像 C# 这样使用名义类型系统的语言中,它不允许我们有一个抽象的 void 方法,当实现时 returns 一个字符串,因为它关注类型等价性,类型必须相同才能相互兼容。

希望对您有所帮助!

结构类型系统:https://en.wikipedia.org/wiki/Structural_type_system

标称类型系统:https://en.wikipedia.org/wiki/Nominal_type_system

Typescript 类型兼容性:https://www.typescriptlang.org/docs/handbook/type-compatibility.html

规格:https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3114-assignment-compatibility