Ignorar erros de texto datilografado "a propriedade não existe no valor do tipo"


227

No VS2013, o edifício para quando o tsc sai com o código 1. Este não foi o caso no VS2012.

Como posso executar minha solução ignorando o erro tsc.exe?

Eu recebo muitos The property 'x' does not exist on value of type 'y'erros, que eu quero ignorar ao usar funções javascript.

Respostas:


303

Eu sei que a pergunta já está fechada, mas eu a encontrei procurando pela mesma TypeScriptException, talvez alguém mais tenha encontrado essa pergunta procurando esse problema.

O problema está na falta da digitação do TypeScript:

var coordinates = outerElement[0].getBBox();

Arremessos The property 'getBBox' does not exist on value of type 'HTMLElement'.


A maneira mais fácil é digitar explicitamente variável como any

var outerHtmlElement: any = outerElement[0];
var coordinates = outerHtmlElement.getBBox();

Editar, final de 2016

Como o operador de conversão preferido do TypeScript 1.6, asessas linhas podem ser compactadas com elegância:

let coordinates = (outerElement[0] as any).getBBox();


Outras soluções

Obviamente, se você quiser fazer o certo, que às vezes é um exagero, você pode:

  1. Crie uma interface própria que simplesmente se estende HTMLElement
  2. Introduzir digitação própria que se estende HTMLElement

14
Você também pode criar uma interface que se estenda HTMLElemente tenha a getBBoxpropriedade adicional . Dessa forma, você ainda obtém a conclusão do código nas outras propriedades.
thetallweeks

em vez de getBBoxusar qualquer um, existe algum método para usar propriamente? gostaria de descobrir o tipo de getBBox?
Pardeep Jain

FE: Se getBBoxfosse do HTMLElementtipo, você poderia converter o objeto nele var typedElement = <HTMLElement> outerHtmlElement;.
michalczukm

4
legais! var coordinates = (<any>outerElement[0]).getBBox();
Bowpunya #

1
Isso realmente não responder à pergunta: "Como ignorar os erros"
Petr Peller

122

A solução rápida e suja é lançar explicitamente para any

(y as any).x

A "vantagem" é que, sendo o elenco explícito, isso será compilado mesmo com o noImplicitAnysinalizador definido.

A solução adequada é atualizar o arquivo de definição de digitações.

Observe que, ao converter uma variável para any, você desativa a verificação de tipo para essa variável.


Como estou no modo de isenção de responsabilidade, a transmissão dupla via anycombinada com uma nova interface pode ser útil em situações nas quais você

  • não deseja atualizar um arquivo de digitações quebrado
  • são remendos de macacos

ainda assim, você ainda deseja alguma forma de digitação.

Digamos que você queira corrigir a definição de uma instância ydo tipo OrginalDefcom uma nova propriedade xdo tipo number:

const y: OriginalDef = ...

interface DefWithNewProperties extends OriginalDef {
    x: number
}

const patched = y as any as DefWithNewProperties

patched.x = ....   //will compile

graças a isso ajudou: import http = require ('http'); servidor var = http como qualquer; server.Server (aplicativo); // ignora os erros ts!
scape

Eu usei isso em "garantir propriedade não encontrada no NodeRequire". então eu declarei minha variável de solicitação em NodeRequired e (exija como qualquer) .ensure para a propriedade. Espero que isto ajude.
Juni Brosas

61

Você também pode usar o seguinte truque:

y.x = "some custom property"//gives typescript error

y["x"] = "some custom property"//no errors

Observe que, para acessar xe não receber um erro de texto novamente, você precisa escrevê-lo assim y["x"], não y.x. Portanto, dessa perspectiva, as outras opções são melhores.


4
Alguém sabe por que isso funciona e se isso tem ramificações ou benefícios em potencial ao declarar inicialmente o objeto como :any?
Mcheah 30/05

Teria o claro benefício de manter as digitações, em vez de converter para qualquer. Eu gostaria de saber por que isso não lança um aviso, mas acessando diretamente faz ..
Powderham

38

Existem várias maneiras de lidar com esse problema. Se esse objeto estiver relacionado a alguma biblioteca externa, a melhor solução seria encontrar o arquivo de definições real (ótimo repositório aqui ) para essa biblioteca e referenciá-lo, por exemplo:

/// <reference path="/path/to/jquery.d.ts" >

Obviamente, isso não se aplica em muitos casos.

Se você deseja 'substituir' o sistema de tipos, tente o seguinte:

declare var y;

Isso permitirá que você faça as chamadas que desejar var y.


5
Deve estar /// <reference path="/path/to/jquery.d.ts" />com a tag de fechamento automático no final
tic

Eu estou usando VS2015 e seguiu este tutorial para angular eu não tenho jquery.d.tsarquivo no meu projeto
Dimple

@Dimple npm install -g tsdthentsd install jquery
Akash

A segunda opção (declarar var y) funciona muito bem se você estiver migrando do JavaScript para o TypeScript e deseja evitar o erro TS2304 porque seu JavaScript antigo está fazendo referência a uma variável em outro arquivo JavaScript.
yesman

Obrigado! Para mim, o problema foi com o Jest, const mockPrompt: any = jest.spyOn (step, 'prompt');
Mark Robson

18

Quando o TypeScript pensa que a propriedade "x" não existe em "y" , você sempre pode converter "y" em "any", o que permitirá chamar qualquer coisa (como "x") em "y".

Teoria

(<any>y).x;

Exemplo do mundo real

Eu estava recebendo o erro "TS2339: a propriedade 'name' não existe no tipo 'Function'" para este código:

let name: string = this.constructor.name;

Então eu o corrigi com:

let name: string = (<any>this).constructor.name;

1
Não funciona com super. Se você estende uma classe usando digitações e o autor esquece um método público, está praticamente ferrado. Você deve adicioná-lo à definição de tipo, que é interrompida na próxima instalação do npm, forçando você a criar uma solicitação de recebimento ou notificar o autor, o que provavelmente é uma coisa boa, mas um problema.
Corey Alix

15

Tive um problema no Angular2, eu estava usando o armazenamento local para salvar algo e isso não me permitiu.

Soluções:

eu tinha localStorage.city -> error -> Property 'city' does not exist on type 'Storage'.

Como corrigi-lo:

localStorage ['cidade']

(localStorage) .city

(localStorage como qualquer) .city


A segunda opção parece legal, mas parece não fazer mais o trabalho. Funciona se você prefixar um objeto com <any>- (<any>localStorage).city.
Jayarjo

Eu sei que isso é antigo, mas o seu melhor exemplo funcionou para mim .. Muito bem.
MacD 6/19/19

4

Uma solução rápida onde nada mais funciona:

const a.b = 5 // error

const a['b'] = 5 // error if ts-lint rule no-string-literal is enabled

const B = 'b'
const a[B] = 5 // always works

Não é uma boa prática, mas fornece uma solução sem a necessidade de desativar no-string-literal


Eu também faço isso, mas algumas plataformas (como o Google Cloud) emitem uma mensagem de aviso sugerindo que ab é melhor que a ['b']. Você sabe por que isso é?
19719 Jonathan

1
Não tenho certeza, mas você pode, em tslint.json, por exemplo, alterar as opções para que ele prefira ab
danday74

3

Sei que agora é 2020, mas não consegui ver uma resposta que satisfizesse a parte "ignorar" da pergunta. Acontece que você pode dizer ao TSLint para fazer exatamente isso usando uma diretiva;

// @ts-ignore
this.x = this.x.filter(x => x.someProp !== false);

Normalmente, isso geraria um erro, afirmando que 'someProp não existe no tipo'. Com o comentário, esse erro desaparece.

Isso interromperá a ocorrência de erros ao compilar e também interromperá a reclamação do IDE.


0

No meu projeto em particular, não consegui fazê-lo funcionar e usado declare var $;. Não é uma solução limpa / recomendada, ela não reconhece as variáveis ​​JQuery, mas não tive erros depois de usá-la (e era necessário que minhas compilações automáticas fossem bem-sucedidas).


0

Consegui superar isso em texto datilografado usando algo como:

let x = [ //data inside array ];
let y = new Map<any, any>();
for (var i=0; i<x.length; i++) {
    y.set(x[i], //value for this key here);
}

Essa parecia ser a única maneira de eu usar os valores dentro de X como chaves para o mapa Y e compilar.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.