Otra forma de ver al tipo de dato never
es como aquellas funciones que nunca llegan a ejecutarse por completo
Introducción
¿Ya tomaste el Curso de Fundamentos de TypeScript?
Configuración del proyecto con ts-node
New Types
Tuples
Enums
Unknown type
Never type
Funciones
Parámetros opcionales y nullish-coalescing
Parámetros por defecto
Parámetros rest
Sobrecarga de funciones: el problema
Sobrecarga de funciones: la solución
Interfaces
Interfaces
Estructuras complejas
Extender interfaces
Propiedades de solo lectura
Proyecto
Ejemplo de CRUD
Omit y Pick Type
Partial y Required Type
Readonly Type
Acceder al tipado por indice
ReadonlyArray
Próximos pasos
Toma el Curso de Programación Orientada a Objetos con TypeScript
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
No se trata de lo que quieres comprar, sino de quién quieres ser. Aprovecha el precio especial.
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Nicolas Molina
El never type se usa para funciones que nunca van a terminar o que detienen el programa. Con esto TypeScript nos ayuda a detectarlos como por ejemplo un ciclo infinito cuando lanzamos un mensaje de error.
En el siguiente código, TypeScript infiere que el tipo es never
, ya que su ejecución será infinita.
const withoutEnd = () => {
while (true) {
console.log('Nunca parar de aprender');
}
}
Las funciones del tipo void
son aquellas que no retornan ningún dato, simplemente ejecutan las instrucciones dentro del bloque de la función. Por tanto, no debemos confundirlas con las de tipo never
:
const voidFunc = () => {
for(let i = 1; i <= 5; i++){
console.log(i)
}
}
voidFunc()
/*
// Función infinita y de tipo Never 👇
const neverFunc = () => {
while (true) {
console.log('Nunca parar de aprender');
}
}
*/
Una función también puede ser del tipo never
cuando tenemos un throw
que lance un error y, como resultado, haga detener la ejecución.
const fail = (message: string) => { // TypeScript infiere que esta función se de tipo `never`
throw new Error(message)
}
const example = (input:unknown) => {
if(typeof input === 'string'){
return 'Es un string';
}
else if (Array.isArray(input)){
return 'Es un array';
}
return fail('Not Match'); // Lanzamos un error
}
console.log(example('Hola')) //'Es un string'
console.log(example([1,1,1,1])) // 'Es un array'
console.log(example(1212)) // error: Uncaught Error: Not Match
console.log(example('Hola después del fail')) // NUNCA SE EJECUTA, porque se lanzó un error previamente
Contribución creada por: Martín Álvarez (Platzi Contributor) con el aporte de Franco Daniel Carrara.
Aportes 26
Preguntas 5
Otra forma de ver al tipo de dato never
es como aquellas funciones que nunca llegan a ejecutarse por completo
El tipo de dato never, más que todo sirve para tipar a una función que nunca va a finalizar o sencillamente que pueda terminar el programa en el caso de lanar una excepción.
Un ejemplo de ello es cuando queremos manejar un error o cuando ejecutamos un loop infinito, como por ejemplo una validación de un token de cada x’s segundos, que es una función que se ejecuta constantemente, ya que lanzas la función, esta envía el token lo valida, y comienza el timer para hacer el refresh de ese token, si hay un error lanza una excepción y si no continúa con la validación y el timer…
// esta funcion no tiene un punto final ya que dispara una excepcion
function error(mensaje: string): never {
throw new Error(mensaje);
}
// esta funcion no tiene un punto final ya que dispara un error
function fallo(): never {
return error("Reportar fallo");
}
// esta funcion no finaliza ya que posee un loop infinito
function loopInfinito() : never {
while(true){}
}```
Si bien esta bueno en caso de funciones donde este tipo de finalización de programas es clara (Como en un while true o el throw), no siempre detecta las funciones que son never.
Estos casos los infiere de tipo void aunque su ejecución sea infinita y detengan la ejecución del resto del programa.
Infiere void:
const badFor = () => {
for(let i = 1; i < 10; i){
console.log(i)
}
}
Infiere void:
const badRecursion = () => {
if(true){
console.log(‘Oh sh*t here we go again’)
badRecursion()
}
}
Si bien TS puede inferir algunas funciones infinitas y que detengan la ejecución no lo hará siempre, por lo que tenemos que seguir haciendo testing 😃
Por lo que vi, never
no es un type que debas declarar como tal.
Es más la inferencia que typescript hace a tu código y determina que ese proceso nunca va a terminar, bien sea un ciclo infinito o un error que detiene el programa.
Encontré hace poco otro caso dónde aparece el never
, en las propiedades de una clase que se inicialzan con un array vacío y no se les define el tipo, así:
class Algo {
miVariable = []; // (property) Algo.miVariable: never[]
}
withoutEnd()
HEROES NEVER TYPE!!!
El uso mas común de never
es cuando por alguna rara razon, necesitamos usar en nuestro codigo un tipado condicional. (conditional-types) ejemplo:
// declaramos un tipo perro
type Dog = {barks : true};
// queremos evaluar un generico que probablemente use union
// de tipos donde se incluya otros animales
type Animals = Dog | Cat | Wolf;
// Creamos un tipo condicional porque algunos casos
// necesitamos exclusivamente el tipo Dog
type ExtractDogish<A> = A extends { barks: true } ? A : never;
const dog : ExtractDogish<Animals> // Dog
const cat: ExtractDogish<Animals> // never
Si necesitas crear una funcion infinita, usa este tipo de dato never.
El tipo “never” en TypeScript representa el tipo de valor que nunca ocurre. Esto significa que una función que nunca retorna o que siempre lanza una excepción tiene un tipo de retorno “never”. El tipo “never” también se utiliza para anotar variables que nunca pueden tener un valor válido.
.
Aquí tienes un ejemplo práctico de cómo se utiliza el tipo “never” en TypeScript:
// Función que lanza una excepción
function throwError(message: string): never {
throw new Error(message);
}
// Función que nunca retorna
function infiniteLoop(): never {
while (true) {
console.log("Este bucle es infinito.");
}
}
// Variable que nunca puede tener un valor válido
let unreachableValue: never;
// Llamada a la función que lanza una excepción
throwError("Se produjo un error.");
// Llamada a la función que nunca retorna
infiniteLoop();
// Asignación de un valor a una variable de tipo "never" (esto dará error)
unreachableValue = 10; // Generará un error: Type '10' is not assignable to type 'never'
En el ejemplo anterior, tenemos una función llamada throwError
que lanza una excepción utilizando la palabra clave throw
. Esta función tiene un tipo de retorno “never” porque nunca retorna un valor normal.
.
También tenemos una función llamada infiniteLoop
que contiene un bucle infinito utilizando la condición true
. Esta función también tiene un tipo de retorno “never” porque nunca sale del bucle y nunca retorna un valor.
.
Además, declaramos una variable unreachableValue
con el tipo “never”, lo que significa que esta variable nunca puede tener un valor válido asignado.
.
Al llamar a la función throwError
y infiniteLoop
, estamos utilizando funciones que tienen un tipo de retorno “never”.
.
Sin embargo, si intentamos asignar un valor a la variable unreachableValue
, como se muestra en el ejemplo, se generará un error porque el tipo “never” no puede tener ningún valor válido asignado.
.
El tipo “never” es útil para indicar situaciones en las que se espera que una función nunca retorne o para anotar variables que nunca pueden tener un valor válido.
.
Espero que este ejemplo práctico te haya ayudado a entender el tipo “never” en TypeScript. Si tienes alguna otra pregunta, ¡no dudes en preguntar!
Pienso que la parte inicial no es clara . Simplemente es para definir algo que no va a ocurrir, en lo que habla al inicio es cimplemente que nunca va tirar un valor de return y en el caso de error es lo mismo nunca va retornar por que siempre ejecuta un error
function throwError(errorMsg: string): never {
throw new Error(errorMsg);
}
Tengo una inquietud! me sale este error al momento de ejecutar el programa,
"\ts-app\dist\04-never.js:8
throw new Error(message);
^
Error: not match
at fail (D:\Users\User\Documents\cursoTypeScript\ts-app\dist\04-never.js:8:11)"
Pero en el código no me arroja ningun inconveniente! ¿Alguien tiene idea de que estoy haciendo mal?
este es mi código;
const fail = (message: string)=>{
throw new Error(message);
}
const example=(input: unknown)=> {
if (typeof input === ‘string’) {
return ‘es un string’;
} else if (Array.isArray(input)) {
return ‘Es un array’;
}
return fail(‘not match’);
}
console.log(example(‘Hola’));
console.log(example([1,2,3]));
console.log(example(12));
console.log(example(‘Hola despues del fail’));
Detectar un array
Never Type
También puede servir para las funciones que se encargan del monitoreo de cierta información cada cierto tiempo, como por ejemplo un servicio de OneDrive que cada 5 minutos pregunta a la “nube” si hay algunos archivos nuevos que el usuario actual no tenga en un directorio sincronizado.
Si bien el proceso de revisar termina, el proceso del monitoreo es continuo y sin fin.
No me convenció, nunca llamó a la función: withoutEnd, ni tampoco al tipo de dato never.
Entiendo el tipo never
en las funciones como aquellas funciones que nunca retornan al flujo de su llamado.
Por ej. si ejecutas la función withoutEnd
, nunca retornará, porque es un ciclo infinito. Imprimirá por siempre nunca pares de aprender.
Al ejecutarse la función example
en la linea 24, esta a su vez llamará a la función fail
, la cual lanza un error y por tanto nunca retorna, y es por ello que no se ejecuta la linea 25
La diferencia con el return void, es que estas funciones aunque no retornen un valor como tal, el flujo si retorna a su llamado normalmente, de hecho puedes colocar un return. En el sig ejemplo la función se ejecuta, imprime Hi, retorna al flujo y luego imprime Hello.
const _print = (message: string) : void => {
console.log(message)
return
}
_print('Hi')
console.log("Hello")
Notas de clase:
// esta funcion no finaliza ya que posee un loop infinito
const withoutEnd=()=>{
while (true) {
console.log('Nunca pares de aprender');
}
}
// esta funcion no tiene un punto final ya que dispara una excepcion
const fail = (message:string)=>{
throw new Error(message);
}
const example = (input:unknown)=>{
if (typeof input === 'string') {
return 'Esto es un string';
}else if(Array.isArray(input)){
return 'Esto es un array';
}
return fail('not match');
}
console.log(example('Hola'));
console.log(example([1,2,3,4]));
console.log(example(123)); // se detiene
console.log(example('Hola despues del fail'));
endless()
const withoutEnd = () => {
while (true) {
console.log('nunca para de aprender');
}
}
const fail = (message: string) => {
throw new Error(message);
}
const example = (input: unknown) => {
if (typeof input === 'string') {
return 'es un string';
} else if (Array.isArray(input)) {
return 'es un array';
}
return fail('not match');
}
console.log(example('Hola'));
console.log(example([1,1,1,1]));
console.log(example(1212)); // detiene
console.log(example('Hola despues del fail'));
console.log(example('Hola despues del fail'));
console.log(example('Hola despues del fail'));
Never type sirve para detener de forma forzada la ejecución de algún programa. Esto lo podemos definir mediante una función que retorna un throw error o simplemente definiendo el type never.
y ese doble 01 nunca se cambio… jaja es broma gran curso hasta el momento!
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?