Руководство по стилю и соглашения по кодированию¶
Люди спрашивали меня, что я думаю по этому поводу. Лично я не навязываю их своим командам и проектам, но эти соглашения отлично выступают мировым судьёй и полезны для поддержания консистентности кодовой базы. Есть и другие более важные вещи и они описаны в главе с советами (например, утверждение типа это плохо, сеттеры свойств это плохо) 🌹.
Переменная и функция¶
- Используйте
camelCase
для имен переменных и функций
Причина: соглашение в JavaScript
Плохо
var FooVar;
function BarFunc() {}
Хорошо
var fooVar;
function barFunc() {}
Класс¶
- Используйте
PascalCase
для имен классов.
Причина: на самом деле это довольно привычно для стандартного JavaScript.
Плохо
class foo {}
Хорошо
class Foo {}
- Используйте
camelCase
для членов класса и методов
Причина: логично следует из соглашения об именах переменных и функций.
Плохо
class Foo {
Bar: number;
Baz() {}
}
Хорошо
class Foo {
bar: number;
baz() {}
}
Интерфейс¶
- Используйте
PascalCase
для именования.
Причина: аналогично классу
- Используйте
camelCase
для элементов.
Причина: аналогично классу
- Не используйте префикс
I
Причина: нет такого общего соглашения. lib.d.ts
определяет важные интерфейсы без символа I
(например Window, Document и т. д.).
Плохо
interface IFoo {}
Хорошо
interface Foo {}
Тип¶
- Используйте
PascalCase
для именования.
Причина: аналогично классу
- Используйте
camelCase
для элементов.
Причина: аналогично классу
Пространства имен¶
- Используйте
PascalCase
для именования.
Причина: cоглашение, которого придерживается команда TypeScript. Пространства имен фактически представляют собой просто класс со статическими членами. Имена классов: PascalCase
=> имена пространств имен: PascalCase
Плохо
namespace foo {}
Хорошо
namespace Foo {}
Перечисление¶
- Используйте
PascalCase
для именования.
Причина: аналогично классу
Плохо
enum color {}
Хорошо
enum Color {}
- Используйте
PascalCase
для именования элементов перечисления.
Причина: соглашение, которому следует команда TypeScript, то есть создатели языка, например SyntaxKind.StringLiteral
. Это также помогает с переводом (генерацией кода) других языков в TypeScript.
Плохо
enum Color {
red,
}
Хорошо
enum Color {
Red,
}
Null vs. Undefined¶
- Предпочитаю не использовать ни то, ни другое из-за явной недоступности
Причина: эти значения обычно используются для сохранения согласованности между значениями. В TypeScript вы используете типы для указания структуры
Плохо
let foo = { x: 123, y: undefined };
Хорошо
let foo: { x: number; y?: number } = { x: 123 };
- Используйте
undefined
в общем случае (но рассмотрите возможность возврата такого объекта, как{valid:boolean, value?:Foo}
вместо этого)
Плохо
return null;
Хорошо
return undefined;
- Используйте
null
, если он является частью API или является традиционным
Причина: это обычное дело в Node.js, например error
имеет значение null
для колбэков.
Плохо
cb(undefined);
Хорошо
cb(null);
- Используйте проверку на истинность объектов, являющихся
null
илиundefined
Плохо
if (error === null)
Хорошо
if (error)
- Используйте
== null
/!= null
(а не===
/!==
) для проверки наличияnull
/undefined
в примитивах, но не для других ложных значений (например''
,0
,false
), например:
Плохо
if (error !== null) // не исключает undefined
Хорошо
if (error != null) // исключает и null и undefined
Форматирование¶
Компилятор TypeScript поставляется с очень хорошим сервисом форматирования. Какой бы результат он ни давал по умолчанию, он достаточно хорош, чтобы уменьшить когнитивную нагрузку в команде.
Используйте tsfmt
для автоматического форматирования кода в командной строке. Кроме того, ваша IDE (atom/vscode/vs/sublime) уже имеет встроенную поддержку форматирования.
Примеры:
// Пробел перед типом, т.е. foo:<пробел>string
const foo: string = 'hello';
Кавычки¶
- Предпочитаю одинарные кавычки (
'
), если не экранирую.
Причина: так делают другие команды JavaScript (например airbnb, standard, npm, node, google/angular, facebook/react). Печатать легче (на большинстве клавиатур shift не требуется). Команда Prettier также рекомендует одинарные кавычки
Двойные кавычки не лишены достоинств: они упрощают копирование и вставку объектов в JSON. Позволяет людям использовать другие языки для работы без изменения символа кавычек. Позволяет использовать апострофы, например He's not going.
Но я бы не стал отклоняться от того, что справедливо решило сообщество JS.
- Если вы не можете использовать двойные кавычки, попробуйте использовать обратные галочки (`).
Причина: обычно они предоставляют возможность удобно работать со сложными строками.
Пробелы¶
- Используйте
2
пробела. Не табы.
Причина: так делают другие команды JavaScript (например airbnb, idiomatic, standard, npm, node, google/angular, facebook/react). Команды TypeScript/VSCode используют 4 пробела, но определенно являются исключениями в экосистеме.
Точка с запятой¶
- Используйте точку с запятой.
Причины: явная точка с запятой помогает инструментам форматирования языка давать стабильные результаты. Отсутствие ASI (автоматическая вставка точки с запятой) может сбить с толку новых разработчиков, например. foo() \n (function(){})
будет одним оператором (а не двумя). TC39 предупреждает об этом. Примеры команд использующих точку с запятой: airbnb, idiomatic, google/angular, facebook/react, Microsoft/TypeScript.
Массив¶
- Описывайте массивы как
foos: Foo[]
вместоfoos: Array<Foo>
.
Причины: легче читать. Это соглашение использует команда TypeScript. Легче узнать, что что-то представляет собой массив, так как мозг обучен обнаруживать []
.
Имя файла¶
Именуйте файлы в camelCase
. Например accordion.tsx
, myControl.tsx
, utils.ts
, map.ts
и т.д.
Причина: стандарт для многих JS-команд.
тип vs. интерфейс¶
- Используйте
тип
, когда вам может понадобиться объединение или пересечение:
type Foo = number | { someProperty: number }
- Используйте
интерфейс
, если вы хотите использоватьextends
илиimplements
, например:
interface Foo {
foo: string;
}
interface FooBar extends Foo {
bar: string;
}
class X implements FooBar {
foo: string;
bar: string;
}
- В иных случаях используйте то, что вам больше нравится.