1

Creio que quiçá, seja reflexo das características da tipagem dinâmica.
É comum em linguagem com tipagem estática ou restrita, seja imposta limitações, ou que seja requerida explicitação do tipo.

Mas não de todo ruim são estas caracteristica, por exemplo, em linguagens de paradigma funcional, é comum haver mônadas que permitem tipos algebricos, como o maybe, ou either.

Pessoalmente, se tens interesse por este caráter da tipagem forte, recomendo o TypeScript que é uma especie de wrapper de JavaScript.

off-topic:
Sobre colocar imagens, também não sei, sou novo na plataforma.

Mas lhe parabenizo por estar a pensar nestas questões, vivemos na era da inteligência artificial, e interesse e curiosidade profunda tornam-se cada vez mais escassos.

Carregando publicação patrocinada...
1

Sensacional, obrigado pela contribuição! Eu realmente sinto falta, mas o JavaScript é excelente, e sim, conheço o TypeScript, mas ele também não me traz conforto ao lidar com exceções. O problema mesmo é não saber se uma função pode lançar uma exceção, e se lançar, qual tipo será. Eu não conheço funcionalidade no TS que faça isso nativamente.

Trabalho com JS há 4 anos e agora, estudando a fundo outras linguagens, percebo o quanto ele tem a melhorar. Mas é como o amigo falou em outro comentário, o próposito dela pode ser assim mesmo e tá tudo bem.

1

TL;DR: Em vez de usar throw usar uniões T|null. Ou para saber exatamente o erro, Either/Result.


Para sinalizar se uma função emite um erro, geralmente eu adoto o paradigma funcional.

Imagine uma função ff que divide dois números reais xx e yy.

f(x,y)=xy,onde x,yR,ey0f(x, y) = \frac{x}{y} , \text{onde } x, y \in \mathbb{R} , \text{e} y \neq 0

Se apenas deseja saber que o erro aconteceu, geralmente a união simples basta.
O erro é sinalizado no contradomínio da função f:R2R{null}f : \mathbb{R}^{2} \to \mathbb{R} \cup \{\text{null}\},

function f(x: number, y: number): number | null {
	if (y === 0) return null;
	return x / y;
}

let x: number = 10;
let y: number = 0;
let z: number|null = f(x, y);

if (z == null) {
	console.error("erro");
}

Entretanto se deseja saber especificamente o erro, isto tende a ser um pouco mais verboso.

type DivError = {
	code: 'DIVISION_BY_ZERO';
};

type Result<T, E> =
 | { ok: true; value: T }
 | { ok: false; error: E };

function f(x: number, y: number): Result<number, DivError> {
	if (y === 0) {
		return {
			ok: false,
			error: {
				code: 'DIVISION_BY_ZERO'
			}
		}
	}
	
	return {
		ok: true,
		value: x / y
	}
}

let x: number = 10;
let y: number = 0;
let z = f(x, y);

if (z.ok) {
	console.log(z.value);
	
} else {
	console.error(z.error.code);
}

Para casos simples a primeira abordagem tende a ser o suficiente. Mas a segunda só recomendo em caso de regras de negocio complexas.