Это правда, что const
утверждения создают объекты и массивы с readonly
элементами. Если вы хотите получить преимущества типа string-literal и tuple, которые дает вам утверждение const
, в то же время не обрабатывая результат, вы можете написать вспомогательную функцию для этого. Я назову это mutable()
:
const mutable = <T>(t: T): { -readonly [K in keyof T]: T[K] } => t
const fruits = mutable(['banana', 'apple', 'orange'] as const);
// const fruits: ["banana", "apple", "orange"]
Это будет работать на один уровень глубже. Если у вас есть вложенные типы объектов / массивов, возможно, вы захотите создать вспомогательную функцию типа DeepMutable
и deepMutable()
:
type DeepMutable<T> =
T extends object ? { -readonly [K in keyof T]: DeepMutable<T[K]> } : T
const deepMutable = <T>(t: T) => t as DeepMutable<T>;
, которая работает так же для приведенного выше случая,
const alsoFruits = deepMutable(['banana', 'apple', 'orange'] as const);
// const alsoFruits: ["banana", "apple", "orange"]
но различие становится важным для вложенных объектов:
const readonlyDeepFruits = {
yellow: ["banana", "lemon"],
red: ["cherry", "apple"],
orange: ["orange", "mango"],
green: ["lime", "watermelon"]
} as const;
/* const readonlyDeepFruits: {
readonly yellow: readonly ["banana", "lemon"];
readonly red: readonly ["cherry", "apple"];
readonly orange: readonly ["orange", "mango"];
readonly green: readonly ["lime", "watermelon"];
} */
const partiallyMutableDeepFruits = mutable(readonlyDeepFruits);
/* const partiallyMutableDeepFruits: {
yellow: readonly ["banana", "lemon"];
red: readonly ["cherry", "apple"];
orange: readonly ["orange", "mango"];
green: readonly ["lime", "watermelon"];
} */
const fullyMutableDeepFruits = deepMutable(readonlyDeepFruits);
/* const fullyMutableDeepFruits: {
yellow: ["banana", "lemon"];
red: ["cherry", "apple"];
orange: ["orange", "mango"];
green: ["lime", "watermelon"];
} */
Хорошо, надеюсь, это поможет. Удачи!
Ссылка на код