Ошибка перегрузки Typescript - PullRequest
0 голосов
/ 13 мая 2018

Я столкнулся с ошибкой, связанной с перегрузкой функции, в машинописном тексте и написал этот минимальный пример для воспроизведения ошибки.

interface XComplex {
  value: X
}
type X = string | XComplex

interface YComplex {
  value: Y
}
type Y = string | YComplex

function transform(v: string): string
function transform(v: XComplex): YComplex
function transform(x: X): Y {
  if (typeof x === "string") {
    return x
  }

  const xValue: X = x.value

  return {
    value: transform(xValue), // <---- **ERROR**
  }
}

// **ERROR**
// [ts]
// Argument of type 'X' is not assignable to parameter of type 'XComplex'.
//   Type 'string' is not assignable to type 'XComplex'.

Ошибка не возникает, если я удаляю перегруженные подписи, но затем следующееварианты использования не будут работать.

// WITH OVERLOADING
const yString1: string = transform('hello')
const yComplex1: YComplex = transform({ value: 'xValue'})
// WITHOUT OVERLOADING
const yString2: Y = transform('hello')
const yComplex2: Y = transform({ value: 'xValue'})

В ошибке кажется, что «Аргументом типа« X »» является xValue, который «не может быть назначен параметру типа« XComplex »», который будет параметромпреобразования.Но преобразование принимает параметр типа X, поэтому я не уверен, что делаю неправильно.


РЕДАКТИРОВАТЬ 1:

Кажется, что если я добавлю дополнительную перегруженную подпись, это сработаеткак положено.

function transform(v: string): string
function transform(v: XComplex): YComplex
function transform(v: X): Y <--- EXTRA OVERLOADED SIGNATURE
function transform(x: X): Y { ... }

Теперь я просто не уверен, почему это необходимо или как понять это из сообщения об ошибке.


РЕДАКТИРОВАТЬ 2:

Подумав об этом больше, я думаю, что поскольку xValue относится к типу X, машинопись не может знать, является ли она строкой или XComplex, и поэтому ни один из

function transform(v: string): string
function transform(v: XComplex): YComplex

не будет соответствовать.Тогда я предполагаю, что машинописный текст просто просматривает подписи одну за другой, пока не достигнет последней и не обнаружит ни одного совпадения, поэтому он просто выдает «Аргумент типа« X »не может быть назначен параметру типа« XComplex »».ссылаясь на последнюю подпись.Ошибка, указывающая, что нет совпадения перегруженных подписей, кажется, будет более полезным.

Это объясняет, почему необходим случай «поймать все»

function transform(v: X): Y <--- EXTRA OVERLOADED SIGNATURE

.

1 Ответ

0 голосов
/ 13 мая 2018

Сигнатура реализации перегрузки не вызывается, поэтому, если вы хотите иметь вызываемую версию вашей перегрузки, которая принимает X, вам нужно добавить для нее сигнатуру без реализации.

При использовании перегрузок подпись реализации не может быть вызвана напрямую, поэтому все вызовы должны быть совместимы с одной из перегрузок - Pro TypeScript p39

function transform(v: string): string;     // Overload
function transform(v: XComplex): YComplex; // Overload
function transform(x: X): Y {              // Implementation Signature

Так что, хотя это выглядит как дублирование, правильнаяисправлена ​​дополнительная перегрузка:

function transform(v: string): string;
function transform(v: XComplex): YComplex;
function transform(x: X): Y;
function transform(x: X): Y {
...