Contexto / Reprodução
type Example = {
a: string,
b: number
}
let value: Example = {
a: 'hello',
b: 10,
}
// This IIFE is because typescript will narrow the type if assigned directly like
// const k: keyof Example = 'a'
const k = ((): keyof Example => 'a')()
value = {
...value,
// Obviously this is unsound
[k]: 5,
}
Isso passa mesmo no modo estrito. Link do playground .
Pergunta
Por que o typescript é inseguro aqui? Quero entender a insegurança geral para que eu possa evitar usar padrões como esse que não serão typesafe. Eu também apreciaria qualquer documentação relevante ou problemas do GitHub.
Este é um problema conhecido com TypeScript, documentado em microsoft/TypeScript#38663 . Se você tiver um nome de propriedade computado cujo tipo é um union , então TypeScript ampliará esse tipo até
string
(veja microsoft/TypeScript#13948 ), e então mais ou menos ignorará a propriedade completamente. Ou seja, é ainda pior do que possivelmente atribuir umnumber
aa
, ele poderia atribuir qualquer coisa aa
, incluindofalse
(veja este link de playground ).Atualmente, não é classificado como um bug, provavelmente porque essas inconsistências com gravações de propriedades permeiam a linguagem:
Corrigir tal insegurança tornaria as coisas mais seguras, mas sem dúvida muito mais irritantes de usar, como evidenciado pelas muitas reclamações sobre microsoft/TypeScript#30769 . TypeScript é inseguro, principalmente em lugares onde a equipe do TS acha que a cura é pior do que a doença. Veja TypeScript Language Design Non-Goal #3 e comentários da equipe do TS em microsoft/TypeScript#9825 .