Как typeScript core.ts собирается без ошибки перегрузки? - PullRequest
2 голосов
/ 14 апреля 2019

Эти строки кода ...

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;
}

... существует в строке 702 компилятора / core.ts в источнике реализации компилятора TypeScript.

Почему эта компиляция не вызывает ошибку перегрузки?

Я спрашиваю, потому что я ожидаю, что это произойдет с ошибкой по той же причине, показанной в первом примере ниже - то есть при попытке передать 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> в качестве входного параметра (но не наоборот)
  • Проверка ошибок перегрузки проверяет только типы входных параметров, а не типы возврата

1 Ответ

1 голос
/ 14 апреля 2019

Если вы отметите tsconfig-base.json , вы заметите, что не все строгие опции включены.Наиболее примечательно для вашего вопроса, strictFunctionTypes не включен.

Это означает, что компилятор будет гораздо более расслаблен в отношении совместимости функций, alowinf параметры функции, чтобы относиться бивариантно (вы можете прочитать больше здесь ).Хотя в PR явно не упоминаются перегрузки, в целом это влияет на совместимость сигнатур функций, поэтому имеет смысл, что это также повлияет на совместимость с перегрузками.Так, например, это присвоение недопустимо в strictNullChecks, но допустимо без него:

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