Eu sempre compilei o Typecript com a flag --noImplicitAny. Isso faz sentido, pois quero que minha verificação de tipo seja o mais rígida possível.
Meu problema é que, com o seguinte código, recebo o erro Index signature of object type implicitly has an 'any' type
:
interface ISomeObject {
firstKey: string;
secondKey: string;
thirdKey: string;
}
let someObject: ISomeObject = {
firstKey: 'firstValue',
secondKey: 'secondValue',
thirdKey: 'thirdValue'
};
let key: string = 'secondKey';
let secondValue: string = someObject[key];
Importante notar é que a ideia é que a variável chave venha de algum outro lugar no aplicativo e possa ser qualquer uma das chaves no objeto.
Eu tentei converter explicitamente o tipo por:
let secondValue: string = <string>someObject[key];
Ou o meu cenário simplesmente não é possível --noImplicitAny
?
fonte
Outra maneira de evitar o erro é usar o elenco assim:
let secondValue: string = (<any>someObject)[key];
(Observe os parênteses)O único problema é que isso não é mais seguro para o tipo, como você está usando
any
. Mas você sempre pode voltar ao tipo correto.ps: Estou usando o texto datilografado 1.7, não tenho certeza sobre as versões anteriores.
fonte
let secondValue: string = (someObject as any)[key];
O TypeScript 2.1 introduziu uma maneira elegante de lidar com esse problema.
Podemos acessar todos os nomes de propriedades de objetos durante a fase de compilação por
keyof
palavra-chave (consulte changelog ).Você só precisa substituir o
string
tipo de variável porkeyof ISomeObject
. Agora, o compilador sabe que akey
variável pode conter apenas nomes de propriedadesISomeObject
.Exemplo completo:
Código ativo em typescriptlang.org (
noImplicitAny
opção definida )Leitura adicional com mais
keyof
usos .fonte
key
comoconst key = (keyof ISomeObject)
= 'segundo' + 'Chave'A seguinte configuração do tsconfig permitirá que você ignore esses erros - defina-o como true.
fonte
--noImplicitAny
. Combine perfeitamente a pergunta do op.XMLHttpRequest
.keyof
operador TS2.1 pode ajudar a manter tudo rígido, veja a resposta da Piotr!A solução 'keyof' mencionada acima funciona. Mas se a variável for usada apenas uma vez, por exemplo, percorrendo um objeto, etc, você também poderá convertê-lo.
fonte
usar
keyof typeof
fonte
Semelhante à resposta de @Piotr Lewandowski, mas dentro de
forEach
:fonte
Argument of type '(field: "id" | "url" | "name") => void' is not assignable to parameter of type '(value: string, index: number, array: string[]) => void'
. Meu código é assimObject.keys(components).forEach((comp: Component) => {...}
, ondeComponent
é um tipo (comoMyConfig
).Declare o objeto assim.
fonte
Nenhum indexador? Então faça o seu!
Eu defini isso globalmente como uma maneira fácil de definir uma assinatura de objeto.
T
pode ser,any
se necessário:Acabei de adicionar
indexer
como um membro da classe.Então, acabo com isso:
O benefício de fazer isso é que você recebe o tipo adequado de volta - muitas soluções usadas
<any>
perdem a digitação para você. Lembre-se de que isso não realiza nenhuma verificação de tempo de execução. Você ainda precisará verificar se existe algo, se não tiver certeza.Se você deseja ser excessivamente cauteloso, e está usando,
strict
você pode fazer isso para revelar todos os lugares em que pode ser necessário fazer uma verificação indefinida explícita:Normalmente, não acho isso necessário, pois, se eu tiver uma propriedade string de algum lugar, geralmente sei que é válida.
Achei esse método especialmente útil se tiver muito código que precisa acessar o indexador e a digitação pode ser alterada em apenas um local.
Nota: estou usando o
strict
modo, e ounknown
é definitivamente necessário.O código compilado será apenas
indexer = this
, portanto, é muito semelhante a quando o texto datilografado é criado_this = this
para você.fonte
Record<T>
tipo - no momento, não sou capaz de pesquisar os detalhes, mas, em alguns casos limitados, pode funcionar melhor.Crie uma interface para definir a interface 'indexador'
Em seguida, crie seu objeto com esse índice.
Nota: isso ainda terá os mesmos problemas que outras respostas descreveram em relação à imposição do tipo de cada item - mas geralmente é exatamente isso que você deseja.
Você pode criar o parâmetro de tipo genérico do que precisar:
ObjectIndexer< Dog | Cat>
Parque de diversões
Você pode até usar isso em uma restrição genérica ao definir um tipo genérico:
export class SmartFormGroup<T extends IndexableObject<any>> extends FormGroup
Então
T
dentro da classe pode ser indexado :-)fonte
Dictionary
isso{ [key: string]: T }
, mas se houver, edite esta pergunta para remover minhaObjectIndexer
.Declare o tipo em que sua chave é string e o valor pode ser qualquer um e, em seguida, declare o objeto com esse tipo e o fiapo não será exibido
Portanto, seu código será
fonte
Atualmente, a melhor solução é declarar tipos. Gostar
fonte
A solução mais simples que eu encontrei usando o Typescript 3.1 em 3 etapas é:
1) Faça interface
2) Faça uma cópia digitada
3) Use em qualquer lugar (JSX incluído)
fonte