Комментарии 26
Кстати, а есть простая возможность включать strict на уровне файла? Ну или включить на проекте и выключать на уровне файла?
Разве линтера? По крайней мере, собственно параметр strict — это параметр typescript, а не tslint. А в typescript можно ли локально игнорировать определённые правила? Для произвольной ошибки — да, есть // @ts-ignore
, а для конкретной проверки?
пожалуйста перестаньте использовать ts-lint и переходите на eslint с плагинами для тайпскрипт. сразу почувствуете разницу в лучшую сторону. для eslint удобно отключать правила как глобально так и локально.
function getUserType(id: number): string { /*… */ }
function getUserType(id: number): 'standard' | 'premium' | 'admin' { /*… */ }
Вы пишете, что вторая функция лучше, так как более информативна. Но что делать, если (когда) добавится новый тип юзеров, 'banned', например? Ходить по всем таким функциям и исправлять?
А если мы пишем аналогичные функции getUserCountryName и getUserCurrencyCode — тоже в них все 150 возможных ответов перечислять?
Можно тип объявить. Я думаю, автор написал инлайн-объявление просто для примера.
export type UserType='standard' | 'premium' | 'admin' ;
тогда объявление функции приобретет такой вид:
function getUserType(id: number):UserType { /*… */ }
А если мы пишем аналогичные функции getUserCountryName и getUserCurrencyCode — тоже в них все 150 возможных ответов перечислять?
тут тип возвращаемого функцией значения скорее всего будет просто «string»
А если мы пишем аналогичные функции getUserCountryName и getUserCurrencyCode — тоже в них все 150 возможных ответов перечислять?
Тут зависит от ситуации.
enum CountryCodeEnum {
US = 'US',
// ...
RU = 'RU',
}
enum UserTypeEnum {
STANDARD = 'standard',
PREMIUM = 'premium',
ADMIN = 'admin'
}
interface IUser {
id: number;
name: string;
age: number;
type: UserTypeEnum;
country: CountryCodeEnum;
}
function getCountryCode(user: IUser): CountryCodeEnum {
return user.country;
}
В комментариях к оригинальной статье автору советуют использовать enum для подобных случаев: https://dev.to/lexlohr/comment/d831
export type UserType = 'standard' | 'premium' | 'admin'
Также хорошая альтернатива — string enum:
export enum UserType { Standard = 'standard' /*...*/ }
2. Это немного другой сценарий — очень много вариантов. Например, зачастую конкретные currencyCode при этом просто не используются — все приходит с сервера или выбирается юзером. Но если они все таки нужны, можно решить проблему константами, например ввести DEFAULT_CURRENCY_CODE для предзаполнения дропдауна. Система типов для этого полезна, но не является оптимальным решением.
Вот только сегодня доработал этот подход, способом возможным с, кажется, 3.4:
// possible values
const statuses = ["new", "approving", "approved", "published", "depublished"] as const;
// pseudo-enum
export type Status = typeof statuses[number];
// type guard
export const isStatus = (value: any): value is Status => (
typeof value === 'string' && statuses.some(status => status === value)
);
- читать код реализации функции может быть довольно утомительно просто в силу объема
- по деталям реализации может быть не совсем понятно, что именно делает функция
- подобное описание может использоваться для генерации документации
- значит функция недостаточно декомпозирована
- это должно быть понятно из её имени
- вот тут согласен, правда некоторые средства генерации документации иногда ведут себя странно, игнорируют фактическую сигнатуру функции, перекрывая её тем, что описано в в doc. Почему я от них отказался для внутренних разработок. *doc должен дополнять код, а не переопределять его.
В любом случае плохо бросаться
значит функция недостаточно декомпозирована
Я не очень понял как декомпозиция сделает поведение функции более понятно
notSimpleFunction (someArg) {
// A lot of code
}
станет
notSimpleFunction(someArg) {
// firstSimpleFunction(someArg)
// realyEasyFunction(someArg[1])
// makeItEasy()
}
код функции может и станет проще понять, но ее поведение (то есть что она возвращает от принятых данных) понять проще не станет
5 заповедей TypeScript-разработчика