Tslint: interface-over-type-literal não deve ser recomendado

Criado em 25 set. 2017  ·  18Comentários  ·  Fonte: palantir/tslint

Sim, eu sei que os documentos do Typescript dizem

Como uma propriedade ideal do software está sendo aberta à extensão, você deve sempre usar uma interface sobre um alias de tipo, se possível.

mas falando sério, se estou fazendo um tipo simples com nenhuma intenção de usá-lo como algo extensível, não faz sentido codificá-lo como uma interface.

API Breaking Change Enhancement

Comentários muito úteis

Eu sei que posso substituí-lo, mas sinto fortemente que a recomendação está incorreta.

Aqui está a minha visão disso. Há muitos casos em que uma interface não pode ser usada para um alias de tipo. Você só pode usar uma interface para digitar um literal de objeto. Se eu seguir as melhores práticas recomendadas, em um arquivo de classe específico onde eu possa ter vários aliases de tipo, alguns serão aliases de tipo e alguns serão interfaces. Alguém se deparar com essa classe vai se perguntar o que diabos está acontecendo e se estou pretendendo que as interfaces sejam implementadas/estendidas em algum lugar, ou pelo menos esperando que seja uma possibilidade.

Seria muito mais limpo na minha opinião usar um alias de tipo para um alias de tipo e uma interface para uma interface, em vez de substituir uma pela outra em alguns casos apenas porque as interfaces têm alguma capacidade extra (que eu não preciso se all want for um tipo de alias).

Suponho que devo escrever um problema contra os documentos datilografados, o que farei, mas acho que algum julgamento de engenharia pode ser aplicado aqui em vez de implementar uma regra apenas porque os documentos dizem que você deveria.

Todos 18 comentários

Desculpe, não entendi o que você quer dizer. Isso é uma solicitação de recurso ou um relatório de bug?

O valor padrão para interface-over-type-literal em recomendado.ts é true. Acredito que deveria ser falso. Não tenho certeza se isso constitui uma solicitação de recurso ou um bug :-)

Afinal o preset recomendado é opinativo. Ele incorpora as melhores práticas e sugestões como a que você postou acima.
Ao estender uma predefinição, você pode substituir a recomendação e ajustar a configuração às suas necessidades.

De qualquer forma, desabilitar a regra seria uma mudança radical. Portanto, não espere nenhuma mudança antes da próxima versão principal.


Para esclarecer: interface-over-type-literal apenas reclama de declarações de tipo alias.

type Foo = {foo: number}; // The rule disallows this
interface Foo {foo: number} // and fixes it to this

let obj: {foo: number}; // This is still allowed

Como um alias de tipo e uma interface podem ser usados ​​(quase) de forma intercambiável, não vejo por que você preferiria o alias de tipo.

Em uma nota relacionada: as interfaces costumavam ser armazenadas em cache enquanto tipos anônimos, como aliases de tipo, eram recalculados para uso contínuo. Portanto, usar aliases de tipo pode aumentar significativamente o tempo de compilação.
Essa lacuna de desempenho quase desaparecerá com a próxima versão datilografada.

Eu sei que posso substituí-lo, mas sinto fortemente que a recomendação está incorreta.

Aqui está a minha visão disso. Há muitos casos em que uma interface não pode ser usada para um alias de tipo. Você só pode usar uma interface para digitar um literal de objeto. Se eu seguir as melhores práticas recomendadas, em um arquivo de classe específico onde eu possa ter vários aliases de tipo, alguns serão aliases de tipo e alguns serão interfaces. Alguém se deparar com essa classe vai se perguntar o que diabos está acontecendo e se estou pretendendo que as interfaces sejam implementadas/estendidas em algum lugar, ou pelo menos esperando que seja uma possibilidade.

Seria muito mais limpo na minha opinião usar um alias de tipo para um alias de tipo e uma interface para uma interface, em vez de substituir uma pela outra em alguns casos apenas porque as interfaces têm alguma capacidade extra (que eu não preciso se all want for um tipo de alias).

Suponho que devo escrever um problema contra os documentos datilografados, o que farei, mas acho que algum julgamento de engenharia pode ser aplicado aqui em vez de implementar uma regra apenas porque os documentos dizem que você deveria.

O uso da palavra-chave interface para estruturas deve ser desencorajado na minha opinião. Essa regra faz exatamente o oposto, então não há como isso ser considerado uma prática recomendada.

Esta é uma das coisas que o typescript errou na minha opinião, isso está confundindo o conceito de interface, cuja semântica em todas as outras linguagens typesafe que usei, significa "uma coleção de métodos/funções/coisas que podem ser chamadas", com assinatura de objeto/ tipo de pato. O uso da interface deve ser mais restritivo, e eu realmente gostaria de uma regra TSLint "interface-must-declare-only-functions" ou uma "interface-must-declare-at-least-one-function" menos restritiva

Estruturas puras devem ser declaradas usando o operador de tipo e estendidas usando o operador &. E o nome deve começar com "T" :-)

@navels Concordo com seu feedback, acho que tslint:recommended deve remover essa configuração de regra excessivamente opinativa como uma alteração importante na próxima versão principal

como posso substituir esta opção?

@sibelius em seu tslint.json , em "rules" , marque-o como false :

{
    "extends": ["tslint:recommended"],
    "rules": {
        "interface-over-type-literal": false
    }
}

Observe que esse problema está rastreando a desativação da regra no conjunto de regras recomendado. Se você tiver dúvidas gerais sobre o TSLint, use StackOverflow ou Gitter.

Aqui alguém fala sobre esse assunto https://medium.com/@martin_hotell/interface -vs-type-alias-in-typescript-2-7-2a8f1777af4c

Sobre substituir a regra, eu preferiria a opção de me forçar a usar o tipo em vez da interface ou ainda melhor, me forçar a usar o tipo apenas se estiver definindo um Props ou State no meu react componente.

Escrevo cada vez menos código OOP a ponto de não usá-lo em meu projeto atual.
Eu não gostaria que os iniciantes fossem empurrados para isso.

@dandrei e eu usamos apenas Interfaces, quando quero descrever funções (também não uso OOP).

Sim, este está definitivamente errado e o IMO não deve fazer parte do recomendado, ou pelo menos não corrigido automaticamente para que possamos desativá-lo antes que ele destrua nossos tipos.

A recomendação realmente quebra o código. Considerar:

type Foo = {
  foo: string
}

interface IndexedObject {
  [key: string]: string
}

function useIndexedObject(object: IndexedObject) {}

const foo: Foo = {foo: "foo"}
useIndexedObject(foo)

O código acima funciona. Até que tslint --fix seja aplicado e mude type Foo para interface Foo , a última linha produz o erro:

Argument of type 'Foo' is not assignable to parameter of type 'IndexedObject'.
  Index signature is missing in type 'Foo'.

IMO, qualquer regra que quebre o código não deve ser uma recomendação. Caramba, nem deveria ser uma regra se tiver o potencial de quebrar o código.

Não só isso, mas também faz com que a regra "interfaces devem começar com 'I'".

error TS2344: ...
Index Signature is missing in type 'SOME INTERFACE'.

então eu tenho que usar o tipo .

Se seus aplicativos tiverem muito uso de type , é um bom indicador de violações dos princípios SOLID.

Removendo o rótulo Type: Breaking Change conforme #4811. Agora aceitando PRs!

Então, por que é chamado de TypeScript, quando deveria ser chamado de InterfaceScript?! 🤣

Esta página foi útil?
0 / 5 - 0 avaliações