Você não pode alterar o tipo de uma propriedade existente.
Você pode adicionar uma propriedade:
interface A {
newProperty: any;
}
Mas mudando um tipo de existente:
interface A {
property: any;
}
Resulta em um erro:
As declarações de variáveis subsequentes devem ter o mesmo tipo. A variável 'propriedade' deve ser do tipo 'número', mas aqui tem o tipo 'qualquer'
É claro que você pode ter sua própria interface que estende uma já existente. Nesse caso, você pode substituir um tipo apenas por um tipo compatível, por exemplo:
interface A {
x: string | number;
}
interface B extends A {
x: number;
}
A propósito, você provavelmente deve evitar usar Object
como um tipo, em vez disso, use o tipo any
.
Nos documentos do any
tipo, ele afirma:
O any type é uma maneira poderosa de trabalhar com o JavaScript existente, permitindo que você gradualmente aceite e desative a verificação de tipo durante a compilação. Você pode esperar que Object desempenhe uma função semelhante, como em outras linguagens. Mas variáveis do tipo Object permitem apenas que você atribua qualquer valor a elas - você não pode chamar métodos arbitrários sobre elas, mesmo aqueles que realmente existem :
let notSure: any = 4;
notSure.ifItExists(); // okay, ifItExists might exist at runtime
notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check)
let prettySure: Object = 4;
prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'.
Eu uso um método que primeiro filtra os campos e depois os combina.
referência Excluir propriedade do tipo
para interface:
fonte
extend
funcionasse por padrão, mas, infelizmente, issoOmit
corrige tudo 🙌Inspirado pela solução ZSkycat
extends Omit
, eu vim com isto:Exemplo:
Passo a passo:
Tipos de utilitários TypeScript
fonte
Estendendo um pouco a resposta de @zSkycat, você pode criar um genérico que aceita dois tipos de objeto e retorna um tipo mesclado com os membros do segundo substituindo os membros do primeiro.
fonte
Omit
a propriedade ao estender a interface:fonte
É engraçado eu passar o dia investigando a possibilidade de resolver o mesmo caso. Descobri que não é possível fazer desta forma:
Causa Um módulo pode não saber sobre todos os tipos disponíveis em seu aplicativo. E é muito chato portar tudo de qualquer lugar e fazer código como este.
Você precisa definir o tipo mais tarde para que o preenchimento automático funcione bem.
Então você pode trapacear um pouco:
Deixou alguns tipos por padrão, que permitem trabalhos de preenchimento automático, quando as substituições não são necessárias.
Então
Desative a exceção estúpida aqui usando
@ts-ignore
flag, dizendo que estamos fazendo algo errado. E o engraçado é que tudo funciona conforme o esperado.No meu caso estou reduzindo a visão do escopo do tipo
x
, isso me permite fazer código mais restrito. Por exemplo, você tem uma lista de 100 propriedades e reduz para 10, para evitar situações estúpidasfonte
Para restringir o tipo da propriedade, o simples
extend
funciona perfeitamente, como na resposta de Nitzan :Para ampliar, ou geralmente substituir o tipo, você pode fazer a solução do Zskycat :
Mas, se a sua interface
A
estender uma interface geral, você perderá os tipos personalizados dasA
propriedades restantes de ao usarOmit
.por exemplo
O motivo é que
Omit
internamente apenas analisa asExclude<keyof A, 'x'>
chaves, o que será o geralstring | number
em nosso caso. Portanto,B
se tornaria{x: number; }
e aceitaria qualquer propriedade extra com o tipo denumber | string | boolean
.Para corrigir isso, criei um
OverrideProps
tipo de utilitário diferente, como segue:Exemplo:
fonte
Se outra pessoa precisar de um tipo de utilitário genérico para fazer isso, eu encontrei a seguinte solução:
Eu precisava disso porque, no meu caso, a chave a ser substituída era o próprio genérico.
Se você não tiver
Omit
pronto, consulte Excluir propriedade do tipo .fonte