Комментарии 16
Не совсем ясна суть примера, но, теоретически, решение с заданием статического типа для переменной ключа, может быть лучше масштабируемым:
type OpenDoorKey = 'open_door_pls';
const wallet = {
key: "open_door_pls" as OpenDoorKey,
};
function openDoor(key: OpenDoorKey): void {
console.log("The door is now open!");
}
openDoor(wallet.key);
Употребляйте термин строгая типизация корректно. В статье идёт речь про точные типы или литеральные типы. Строгая типизация это отсутствие неявного преобразования типов и отсутствие каламбура типов.
Статье для полноты не хватает реализации метода deepFreeze с поддержкой точного типа.
as const
уточняет тип и выдает ошибки модификации во время транспиляции. Но если передать этот объект js-коду или сделать as any, то можно будет модифицировать этот объект. Поэтому важно не только делать типas const
но и защищать объект от посягательств кода третьих лиц.
Отличные замечания. А а какой момент может произойти модификация объекта? (В сорце? В рантайме? При транспиляции?)
Кстати, чтобы написать такую функцию deepFreeze
, весьма полезен новый модификатор const
для праметров типов в дженериках из TypeSscript 5. Вот простейший пример реализации с ним:
/* ? */
function deepFreeze<const T extends object>(obj: T): T {
Object.freeze(obj);
Object.values(obj)
.filter(nested => nested !== null && typeof nested === 'object')
.forEach(deepFreeze);
return obj;
}
// const frozen: readonly ["a", {readonly b: 1;}]
const frozen = deepFreeze(["a", {b: 1}]);
Без него всякий раз пришлось бы лишний раз писать as const
const frozen = deepFreeze(["a", {b: 1}] as const);
Подробнее про модификатор const
в документации TS.
По поводу использования const assertion в качестве «замены enum»: рекомендую посмотреть в сторону конструкции `const enum` — она объединяет лучшее из обоих миров.
Хороший вариант. Главное помнить о подводных камнях:
https://www.typescriptlang.org/docs/handbook/enums.html#const-enum-pitfalls
Начались костыли как в JS.
Вам не кажется что писать const ... as const говорит об изначальном косяке в TS, который надо было исправить в любой версии, а не добавлять тавтологию?
Дело в том что const делает неизменной переменной, только вот объекты по ссылке передаются. Защита от изменения у ссылки остается, а вот у внутренностей нет. И хороший вопрос что лучше - защищать целиком или всё же только верхний уровень, удобство кардинально разное. В JS выбрали только ссылки, TS поддержали. Возможно имело бы смысл сделать final в дополнении к const и let, для полной заморозки, но пока дополнительно дописывается дабы не вводить новое ключевое слово.
Object.freeze работает на уровне JS и замораживает объект по настоящему, а вот as const лишь на уровне TS и не защищает от изменений вне компилятора TS. Механизмы очень разные, стоит помнить об этом.
все аргументы из статьи почему enum плох разваливаются об ТС5 (намберы пофиксили) или о понимание почему важно использовать Branding для перечисления.
const enum лучшее решение.
Смотрю со своей колокольни строго типизированных языков, и просто офигеваю...
As const в Typescript