Tslint: interface-over-type-literal не следует рекомендовать

Созданный на 25 сент. 2017  ·  18Комментарии  ·  Источник: palantir/tslint

Да, я знаю, что документы Typescript говорят

Поскольку идеальным свойством программного обеспечения является открытость для расширения, вы всегда должны использовать интерфейс поверх псевдонима типа, если это возможно.

а если серьезно, если я делаю простой тип без намерения когда-либо использовать его как расширяемую вещь, нет смысла кодировать его как интерфейс.

API Breaking Change Enhancement

Самый полезный комментарий

Я знаю, что могу переопределить это, но я твердо уверен, что рекомендация неверна.

Вот мой взгляд на это. Во многих случаях интерфейс нельзя использовать для псевдонима типа. Вы можете использовать интерфейс только для ввода литерала объекта. Если я буду следовать рекомендуемым передовым методам, то в конкретном файле класса, где у меня может быть несколько псевдонимов типов, некоторые будут псевдонимами типов, а некоторые будут интерфейсами. Кто-то, наткнувшись на этот класс, задастся вопросом, что, черт возьми, происходит, и собираюсь ли я где-то реализовать/расширить интерфейсы или, по крайней мере, ожидаю, что это будет возможно.

На мой взгляд, для меня было бы намного чище использовать псевдоним типа для псевдонима типа и интерфейс для интерфейса, а не заменять один на другой в некоторых случаях только потому, что интерфейсы имеют некоторые дополнительные возможности (которые мне не нужны). если все хотят - это псевдоним типа).

Я полагаю, что мне следует написать о проблеме с машинописными документами, что я и сделаю, но я думаю, что здесь можно применить некоторое инженерное суждение, а не применять правило только потому, что документы говорят, что вы должны это сделать.

Все 18 Комментарий

Извините, я не понимаю, что вы имеете в виду. Это запрос функции или отчет об ошибке?

Значение по умолчанию для interface-over-type-literal в файле Recommended.ts равно true. Я считаю, что это должно быть ложным. Не уверен, является ли это запросом функции или ошибкой :-)

Ведь рекомендуемый пресет является самоуверенным. Он включает в себя лучшие практики и предложения, подобные тому, что вы разместили выше.
При расширении предустановки вы можете переопределить рекомендацию и настроить конфигурацию в соответствии со своими потребностями.

В любом случае, отключение правила было бы серьезным изменением. Так что не ждите никаких изменений до выхода следующей основной версии.


Чтобы уточнить: interface-over-type-literal жалуется только на объявления псевдонимов типов.

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

Поскольку псевдоним типа и интерфейс могут использоваться (почти) взаимозаменяемо, я не понимаю, почему вы предпочитаете псевдоним типа.

В связи с этим: интерфейсы раньше кэшировались, а анонимные типы, такие как псевдонимы типов, пересчитывались для постоянного использования. Таким образом, использование псевдонимов типов может значительно увеличить время компиляции.
Этот разрыв в производительности будет почти устранен со следующей версией машинописного текста.

Я знаю, что могу переопределить это, но я твердо уверен, что рекомендация неверна.

Вот мой взгляд на это. Во многих случаях интерфейс нельзя использовать для псевдонима типа. Вы можете использовать интерфейс только для ввода литерала объекта. Если я буду следовать рекомендуемым передовым методам, то в конкретном файле класса, где у меня может быть несколько псевдонимов типов, некоторые будут псевдонимами типов, а некоторые будут интерфейсами. Кто-то, наткнувшись на этот класс, задастся вопросом, что, черт возьми, происходит, и собираюсь ли я где-то реализовать/расширить интерфейсы или, по крайней мере, ожидаю, что это будет возможно.

На мой взгляд, для меня было бы намного чище использовать псевдоним типа для псевдонима типа и интерфейс для интерфейса, а не заменять один на другой в некоторых случаях только потому, что интерфейсы имеют некоторые дополнительные возможности (которые мне не нужны). если все хотят - это псевдоним типа).

Я полагаю, что мне следует написать о проблеме с машинописными документами, что я и сделаю, но я думаю, что здесь можно применить некоторое инженерное суждение, а не применять правило только потому, что документы говорят, что вы должны это сделать.

На мой взгляд, использование ключевого слова interface для структур действительно не рекомендуется. Это правило действует с точностью до наоборот, так что это ни за что не может считаться лучшей практикой.

На мой взгляд, это одна из ошибок машинописного текста, это сбивает с толку концепцию интерфейса, чья семантика во всех других языках безопасности типов, которые я использовал, означает «набор методов/функций/вызываемых вещей» с сигнатурой объекта/ утиный тип. Использование интерфейса должно быть более строгим, и я бы очень приветствовал правило TSLint «интерфейс-должен-декларировать-только-функции» или менее строгий «интерфейс-должен-декларировать-по крайней мере одну-функцию».

Чистые структуры должны быть объявлены с помощью оператора типа и расширены с помощью оператора &. И имя должно начинаться с "Т" :-)

@navels Я согласен с вашим отзывом, я думаю, что tslint:recommended должен удалить эту чрезмерно самоуверенную конфигурацию правил как критическое изменение в следующей основной версии.

как я могу переопределить эту опцию?

@sibelius в вашем tslint.json под "rules" отметьте его как false :

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

Обратите внимание, что эта проблема отслеживает отключение правила в рекомендуемом наборе правил. Если у вас есть общие вопросы по TSLint, используйте StackOverflow или Gitter.

Здесь кто-то говорит на эту тему https://medium.com/@martin_hotell/interface -vs-type-alias-in-typescript-2-7-2a8f1777af4c

Что касается перезаписи правила, я бы предпочел возможность заставить меня использовать тип вместо интерфейса или, что еще лучше, заставить меня использовать тип, только если я определяю Props или State в своем ответе компонент.

Я пишу все меньше и меньше кода ООП до такой степени, что вообще не использую его в своем текущем проекте.
Не хотелось бы, чтобы новичков подталкивали к этому.

@dandrei и я используем только интерфейсы, когда я хочу описать функции (я тоже не использую ООП).

Да, это определенно неправильно, и IMO не должно быть частью рекомендуемых или, по крайней мере, не должно автоматически исправляться, чтобы мы могли отключить его, прежде чем он уничтожит наши типы.

Рекомендация фактически ломает код. Рассмотреть возможность:

type Foo = {
  foo: string
}

interface IndexedObject {
  [key: string]: string
}

function useIndexedObject(object: IndexedObject) {}

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

Приведенный выше код работает. Пока tslint --fix не будет применен и не изменит type Foo на interface Foo , последняя строка выдает ошибку:

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

ИМО, любое правило, нарушающее код, не должно быть рекомендацией. Черт возьми, это даже не должно быть правилом, если оно может сломать код.

Не только это, но также приводит к правилу «интерфейсы должны начинаться с буквы «I».

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

поэтому я должен использовать type .

Если ваши приложения используют много type , это хороший показатель нарушения принципов SOLID.

Удаление метки Type: Breaking Change согласно #4811. Теперь принимаем PR!

Так почему же он называется TypeScript, если он должен называться InterfaceScript?! 🤣

Была ли эта страница полезной?
0 / 5 - 0 рейтинги