Может ли аргумент когда-либо иметь неправильный тип в TypeScript?

Это происходит потому, что функция foo() может принимать только iterables. См. Приведенный ниже пример:

function foo( [a, b, c] ) {
    console.log(a, b, c)
}

foo( [4, 5, 6] );  // works okay

foo( 3,4,5 ); // undefined is not a function

IMHO, spread operator используется в качестве сборщика в этих типах таких как:

function foo( ...[a, b, c] ) {
    console.log(a, b, c)
}

foo( ...[4, 5, 'v'] );  //works fine

foo(1,3,4); // also works fine

Почему foo () генерирует исключение?

Это из-за несовместимых параметров (b / w caller & amp; calee), который не имеет ничего общего с тем фактом, что в JavaScript 1[0] есть undefined.

2
задан lonix 19 January 2019 в 11:27
поделиться

4 ответа

instanceof - это проверка, является ли объект экземпляром Bar. Хотя это означает, что тип параметра также Bar, обратное не всегда верно. Typescript использует структурную типизацию, поэтому любой объект со структурой Bar будет совместим с параметром функции. Так что этот код совершенно корректен:

class Bar {
    bar: number;
}
function doSomething(p: Bar) { }
doSomething({
    bar: 10
})

Когда у вас есть личные свойства, вы не можете так легко «подделать» объект, но даже тогда мы всегда можем утверждать any: [118 ]

class Bar {
    private bar: number;
}
function doSomething(p: Bar) { }
doSomething({ // error now
    bar: 10
})
doSomething({ // breaking out of type safety
    bar: 10
} as any)

И если ваша кодовая база не полностью TS, то любой тип безопасности выходит за пределы окна, JS может вызывать вашу функцию TS с любым, что пожелает.

Значит ли это, что вы всегда должны включать чек? Я бы поспорил против этого. JS довольно свободен в своих типах (как и TS), и именно этого ожидают ваши пользователи. Если это крякает как утка, то это утка, старая мантра JS уходит. Если объект имеет свойства для работы с вашей функцией, он должен работать с вашей функцией независимо от того, как он был создан.

0
ответ дан Titian Cernicova-Dragomir 19 January 2019 в 11:27
поделиться

В TypeScript все работает иначе, чем в JavaScript, если вы передадите аргумент любого другого типа, отличного от того, который указан в сигнатуре функции, вы получите ошибку во время компиляции, и, следовательно, вы обязаны точно следовать типу аргументов функции.

0
ответ дан Manu Bhardwaj 19 January 2019 в 11:27
поделиться

Это зависит от вашей функции. Если это частная функция, доступ к ней имеют только вы, тогда TS может помочь убедиться, что она компилируется, это всегда правильный тип. Если это общедоступная функция, которая должна использоваться другим пользователем / стороной, то необходима проверка, если вы хотите иметь некоторую устойчивость.

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

0
ответ дан bigopon 19 January 2019 в 11:27
поделиться

Чтобы ответить на ваш обновленный вопрос:

Если возможно, что во время выполнения указан неправильный тип, каков механизм, с помощью которого это может произойти? Например, ошибка в приведении типов?

Есть несколько причин, по которым это может произойти:

  • doSomething был вызван из файла JavaScript (без checkJs или @ts-check)
  • Поставляется объект, аналогичный Bar. Это то же самое структурно, но это не случай Bar.
  • Аргумент неверного типа был приведен к Bar другим разработчиком
  • Аргумент неверного типа был автоматически приведен к any (отсутствующие определения типа, потерянный вывод типа)
  • [1115 ] Аргумент неверного типа был утвержден как Bar плохо написанным защитником типа
  • Аргумент неверного типа был обработан как Bar, потому что его определение было дополнено где-то еще в вашем проекте
  • [ 1117] Ваш код был отправлен и использован в среде, где нет конвейера сборки, и поэтому не может существовать ошибок во время компиляции (например, распространяться в виде пакета UMD)
  • Объект или массив были индексированы с использованием не -существующий ключ (TypeScript предполагает, что он никогда не может быть undefined)
  • В миксе используется сомнительно типизированная часть стандартной библиотеки (например, Promise.resolve.call(1) будет выдавать во время выполнения, даже если TypeScript примет это)
0
ответ дан Karol Majewski 19 January 2019 в 11:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: