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.