Isso é definido na especificação de encadeamento opcional do ECMAScript, portanto, provavelmente devemos nos referir ao encadeamento opcional quando discutirmos isso. Provável implementação:
const result = a?.b?.c;
O longo e curto deste é que a equipe do TypeScript está aguardando o aperto da especificação do ECMAScript, para que sua implementação possa ser ininterrupta no futuro. Se eles implementassem algo agora, acabaria precisando de grandes mudanças se o ECMAScript redefinisse sua especificação.
Consulte Especificação de encadeamento opcional
Onde algo nunca será o JavaScript padrão, a equipe do TypeScript pode implementar como achar melhor, mas, para futuras adições ao ECMAScript, eles querem preservar a semântica, mesmo que dêem acesso antecipado, como o fazem para muitos outros recursos.
Cortes curtos
Portanto, todos os operadores funky JavaScripts estão disponíveis, incluindo as conversões de tipo, como ...
var n: number = +myString; // convert to number
var b: bool = !!myString; // convert to bool
Solução Manual
Mas voltando à pergunta. Eu tenho um exemplo obtuso de como você pode fazer algo semelhante em JavaScript (e, portanto, em TypeScript), embora eu definitivamente não esteja sugerindo que seja uma graciosa como o recurso que você realmente procura.
(foo||{}).bar;
Portanto, se foo
is é undefined
o resultado undefined
e se foo
é definido e tem uma propriedade nomeada bar
que possui um valor, o resultado é esse valor.
Eu coloquei um exemplo no JSFiddle .
Isso parece bastante superficial para exemplos mais longos.
var postCode = ((person||{}).address||{}).postcode;
Função Cadeia
Se você está desesperado por uma versão mais curta enquanto a especificação ainda está no ar, eu uso esse método em alguns casos. Ele avalia a expressão e retorna um padrão se a cadeia não puder ser satisfeita ou acabar nula / indefinida (observe que !=
é importante aqui, não queremos usá-lo !==
, pois queremos um pouco de malabarismo positivo aqui).
function chain<T>(exp: () => T, d: T) {
try {
let val = exp();
if (val != null) {
return val;
}
} catch { }
return d;
}
let obj1: { a?: { b?: string }} = {
a: {
b: 'c'
}
};
// 'c'
console.log(chain(() => obj1.a.b, 'Nothing'));
obj1 = {
a: {}
};
// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));
obj1 = {};
// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));
obj1 = null;
// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));