Não consigo entender por que as duas primeiras impressões funcionam, enquanto as outras duas produzem um erro.
const index1 = "name";
const holder: { field: string; } = { field: "name" };
const index2 = holder.field;
const target = { name: "beep" } as MyType;
console.log(target["name"]);
console.log(target[index1]);
console.log(target[holder.field]);
console.log(target[index2]);
O erro diz:
TS7053: O elemento tem implicitamente um tipo 'any' porque a expressão do tipo 'string' não pode ser usada para indexar o tipo 'MyType'.
Nenhuma assinatura de índice com um parâmetro do tipo 'string' foi encontrada no tipo 'MyType'.
Como posso obter um campo por um nome de variável proveniente de uma não constante?
Não encontrei boas respostas abordando esse problema específico de uma forma que eu reconheci. O mais confuso é o fato de que estou usando uma string para obter o campo no objeto em ambos os casos. A única diferença é a const
declaração.
Tentei adicionar as const
de acordo com um exemplo, sem nenhuma diferença.
O valor do campo vem dessa interface. Definitivamente é uma string. No exemplo acima, eu até simplifiquei a definição do tipo.
export interface SortInfo {
field: string;
direction: number;
}
O objeto em si do qual estou tentando obter o campo é declarado por esta interface.
export interface MyType {
id: string;
name: string;
type: number;
...
}
O TypeScript está dizendo que não pode ter certeza de que a chave que você está usando é válida para este objeto.
Assim como
target["foobar"]
não compila, o mesmo acontecetarget[key]
se o tipo dekey
forstring
.Você precisa que o tipo da sua chave seja
keyof typeof target
, ou no seu casokeyof MyType
, que é"id" | "name" | "type" | ...
Você pode definir
holder
como{ field: keyof MyType; }
:Se esse tipo realmente for
SortInfo
, então você pode usarE é claro que se
MyType
pudessem ser coisas diferentes, você usaria genéricos: