2017-01-26 7 views
2

Можно создать DeepReadonly типа так:DeepReadonly Объект машинопись

type DeepReadonly<T> = { 
    readonly [P in keyof T]: DeepReadonly<T[P]>; 
}; 

interface A { 
    B: { C: number; }; 
    D: { E: number; }[]; 
} 

const myDeepReadonlyObject: DeepReadonly<A> = { 
    B: { C: 1 }, 
    D: [ { E: 2 } ], 
} 

myDeepReadonlyObject.B = { C: 2 }; // error :) 
myDeepReadonlyObject.B.C = 2; // error :) 

Это здорово. Оба значения: B и B.C - только для чтения. Когда я пытаюсь изменить D однако ...

// I'd like this to be an error 
myDeepReadonlyObject.D[0] = { E: 3 }; // no error :(

Как я должен написать DeepReadonly так, что вложенные массивы предназначены только для чтения, а?

+0

Я не получаю сообщение об ошибке 'console.log (myDeepReadonlyObject.D [0]);' Какую версию машинописного текста вы используете? –

+0

У меня был флаг «noImplicitAny», установленный в моем tsconfig. Однако вопрос все еще стоит. Я обновил его, чтобы быть более ясным. Благодарю. –

ответ

1

Вы можете иметь только для чтения массив:

interface ReadonlyArray<T> extends Array<T> { 
    readonly [n: number]: T; 
} 
let a = [] as ReadonlyArray<string>; 
a[0] = "moo"; // error: Index signature in type 'ReadonlyArray<string>' only permits reading 

Но вы не можете использовать его с раствором:

interface A { 
    B: { C: number; }; 
    D: ReadonlyArray<{ E: number; }>; 
} 

myDeepReadonlyObject.D[0] = { E: 3 }; // still fine 

Тип D является DeepReadonly<ReadonlyArray<{ E: number; }>>, и это не позволит ReadonlyArray

Я сомневаюсь, что вам удастся заставить его работать с объектами с массивами в них, вы можете иметь либо глубокое чтение только для массива s или для объектов, если вы хотите использовать общий интерфейс/тип, а не конкретные.
Например, это будет работать нормально:

interface A { 
    readonly B: { readonly C: number; }; 
    D: ReadonlyArray<{ E: number; }>; 
} 

const myDeepReadonlyObject = { 
    B: { C: 1 }, 
    D: [{ E: 2 }], 
} as A; 

myDeepReadonlyObject.B = { C: 2 }; // error 
myDeepReadonlyObject.B.C = 2; // error 
myDeepReadonlyObject1.D[0] = { E: 3 }; // error 

Но это имеет определенный интерфейс к нему (A) вместо родового одного DeepReadonly.

Другой вариант - использовать Immutable.js, который поставляется со встроенным файлом определения, и он довольно прост в использовании.

+0

Спасибо. Это настоящий позор, который пока не представляется возможным. Кто-нибудь знает, работает ли это? –

 Смежные вопросы

  • Нет связанных вопросов^_^