TypeScript的core.ts如何在没有重载错误的情况下构建?

问题描述 投票:2回答:1

这些代码行......

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<T>传递给期望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<T>作为其输入参数(但反之亦然)
  • 重载错误检查仅检查输入参数的类型,而不是返回类型
typescript overloading
1个回答
1
投票

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

这意味着编译器将更加轻松的功能兼容性,alowinf函数参数双向关联(你可以阅读更多here)。尽管PR没有明确提及重载,但它确实会影响函数签名兼容性,因此它也会影响过载兼容性。因此,例如,此分配在strictNullChecks下无效,但在没有它的情况下有效:

let fn : <T>(array: ReadonlyArray<T>) =>  ReadonlyArray<T> = function<T>(array: T[]): T[] {
  return array;
}
© www.soinside.com 2019 - 2024. All rights reserved.