Почему typescript не выдает мне ошибку несоответствия типов, которую он должен был (согласно моему пониманию)

#javascript #typescript #typescript-typings

#javascript #typescript #typescript-typings

Вопрос:

По сути, я разработчик javascript, и после многих рекомендаций коллег-разработчиков я начал пробовать typescript (который я нашел совершенно ненужным, без обид), ниже приведен мой код, который имеет массив arr any типа и переменную squares , которая инициализируется массивом, возвращаемым вызываемой map функцией arr , и callback принимает ввод типа number ивозвращает значение типа number , но когда arr содержит string значение, которое оно может с момента его any типа, вместо того, чтобы выдавать ошибку типа, я получаю NaN в этом месте.. пожалуйста, рассмотрите приведенный ниже код

 let arr : Array<any> = [1,2,3,4,'sachin',5,6,7,'naregal',8,9]

let squares = arr.map( (num : number) : number => num * num )

console.log(squares)
  

output : [ 1, 4, 9, 16, NaN, 25, 36, 49, NaN, 64, 81 ]

Комментарии:

1. Потому что typescript компилируется в javascript во время выполнения, а javascript фактически не имеет типов. Таким образом, умножение двух строк дает NaN вместо ошибки типа

2. Typescript обеспечивает безопасность во время компиляции, которую вы как бы отключили при использовании any . Во время выполнения вы запускаете js, который не имеет понятия о типизированных массивах или типизированных параметрах функций и выполняет то, как он определен: когда вам говорят умножить что-то, что не является числом, верните NaN

Ответ №1:

Объявляя ваш массив так, как Array<any> вы в основном говорите TypeScript отступить. any присваивается любому типу, поэтому, когда вы переходите к отображению вашего массива, вы сделали предположение, что элементы будут numbers , и TypeScript позволяет вам делать это по замыслу.

По сути, any в TypeScript есть аварийный люк, который заставит TS заткнуться и оставить все на ваше усмотрение. Обычно рекомендуется не использовать его.

Если вы ожидаете, что ваш массив будет содержать числа и строки, объявите его как Array<number | string> , и TS напомнит вам, когда вы перейдете к отображению над ним.

Имейте в виду, что TypeScript на самом деле не является статически типизированным компилятором, а скорее «утилитой напоминания о типах», и поэтому его можно легко обойти. Например, это допустимый TypeScript:

 const a = 12 as any as string;
console.log(a.toLowerCase()); // no TS warnings, only runtime errors
  

Комментарии:

1. да, я не получил ошибку, даже если я объявил squares массив как тип numbers let squares : Array<number> = arr.map( (num : number) : number => num * num ) это сняло сомнения, я все равно буду придерживаться JS..

Ответ №2:

просто любопытно, ожидали ли вы ошибки во время компиляции или выполнения? Проверка во время выполнения отсутствует.

Поскольку ваш массив имеет тип any , typescript в основном позволяет выполнять все операции с этим массивом (поскольку он не знает его тип).

Вам было бы лучше объявить свой массив как Array<number | string> . Тогда должна быть ошибка, что вы не можете умножить две строки.