Мы можем достичь этого, используя некоторые типы утилит или напрямую сопоставленные типы. Рассмотрим следующее:
type MakeSomePropsReadonly<A, K extends keyof A> = Readonly<Pick<A, K>> & Omit<A, K>
type Original = {
a: string,
b: number,
c: boolean
}
type Example = MakeSomePropsReadonly<Original, 'a'>
const example: Example = {
a: 'a',
b: 1,
c: true
}
example.a = 'b'; // error a property is readonly
example.b = 2; // ok it is not readonly
Что делает наш тип Readonly<Pick<A, K>> & Omit<A, K>
:
Readonly<Pick<A, K>>
- создает тип, который имеет только ключи, выбранные K
, и все все только для чтения , В результате мы получаем только часть типа, которая имеет только эти ключи, которые мы выбираем & Omit<A, K>
мы пересекаем предыдущий сопоставленный типизированный со свойствами только для чтения со второй частью, поэтому Omit<A, K>
создаст объект, который будет иметь все поля с ключом, отличным от K
Итак, мы создаем тип, объединяя один тип со всеми свойствами только для чтения с другим с записываемыми.
Мы также можем сделайте это по-другому, поэтому у нас есть интерфейс «только для чтения», когда вы описываете и выбираете, какие поля доступны для записи:
type MakeSomePropsWritable<A, K extends keyof A> = {
-readonly [Key in K]: A[Key]
} & Omit<A, K>
type Original = {
readonly a: string,
readonly b: number,
readonly c: boolean
}
type Example = MakeSomePropsWritable<Original, 'a'>
const example: Example = {
a: 'a',
b: 1,
c: true
}
example.a = 'b'; // this is now ok as we left it writable
example.b = 2; // this is an error as expected
В этой реализации нет ничего другого, кроме:
-readonly [Key in K]: A[Key]
- мы говорим, что удаляем readonly из этих полей с префиксом -