【问题标题】:How does TypeScript's core.ts build without a overload error?TypeScript 的 core.ts 如何在没有重载错误的情况下构建?
【发布时间】:2019-04-14 07:10:37
【问题描述】:

这几行代码...

export function sameFlatMap<T>(array: T[], mapfn: (x: T, i: number) => T | ReadonlyArray<T>): T[];
export function sameFlatMap<T>(array: ReadonlyArray<T>, mapfn: (x: T, i: number) => T | ReadonlyArray<T>): ReadonlyArray<T>;
export function sameFlatMap<T>(array: T[], mapfn: (x: T, i: number) => T | T[]): T[] {
    let result: T[] | undefined;
    if (array) {
        for (let i = 0; i < array.length; i++) {
            const item = array[i];
            const mapped = mapfn(item, i);
            if (result || item !== mapped || isArray(mapped)) {
                if (!result) {
                    result = array.slice(0, i);
                }
                if (isArray(mapped)) {
                    addRange(result, mapped);
                }
                else {
                    result.push(mapped);
                }
            }
        }
    }
    return result || array;
}

...存在于 TypeScript 编译器实现源中的line 702 of compiler/core.ts

为什么编译时不会产生重载错误?

我之所以问是因为我希望它会因为下面第一个示例中所示的相同原因而出错——即尝试将 ReadonlyArray&lt;T&gt; 传递给需要 T[] 的参数。

为什么不产生这个错误:

src/compiler/core.ts:702:21 - error TS2394: This overload signature is not compatible with its implementation signature.

702     export function sameFlatMap<T>(array: ReadonlyArray<T>, mapfn: (x: T, i: number) => T | ReadonlyArray<T>): ReadonlyArray<T>;

如果我在我的代码中尝试这个,那么这是一个重载错误......

export function foo<T>(array: ReadonlyArray<T>): ReadonlyArray<T>;
export function foo<T>(array: T[]): T[] {
  return array;
}

...虽然这不是错误...

export function baz<T>(array: T[]): T[];
export function baz<T>(array: ReadonlyArray<T>): ReadonlyArray<T> {
  return array;
}

...我猜这是因为:

  • T[] 作为输入参数可以传递给期望 ReadonlyArray&lt;T&gt; 作为其输入参数的函数(反之亦然)
  • 重载错误检查只检查输入参数的类型,而不检查返回类型

【问题讨论】:

    标签: typescript overloading


    【解决方案1】:

    如果您检查tsconfig-base.json,您会注意到并非所有严格选项都已启用。对于您的问题,最值得注意的是,strictFunctionTypes 未启用。

    这意味着编译器将在函数兼容性方面更加宽松,alowinf 函数参数以双变量相关(您可以阅读更多here)。尽管 PR 没有明确提到重载,但它确实会影响函数签名的兼容性,因此它也会影响重载兼容性是有道理的。因此,例如,此分配在 strictNullChecks 下无效,但在没有它时有效:

    let fn : <T>(array: ReadonlyArray<T>) =>  ReadonlyArray<T> = function<T>(array: T[]): T[] {
      return array;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-09-22
      • 2020-03-18
      • 1970-01-01
      • 1970-01-01
      • 2021-08-13
      • 2019-09-30
      • 2021-06-14
      • 2023-03-03
      • 1970-01-01
      相关资源
      最近更新 更多