Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TypeScript and Immutability

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

TypeScript and Immutability

TypeScriptでImmutableなエンティティを表現する方法あれこれ

More Decks by Taketoshi Aono(青野健利 a.k.a brn)

Other Decks in Programming

Transcript

  1. type Primitive = undefined | null | boolean | string

    | number | Function;! ! interface ConstArray<T> extends ReadonlyArray<Const<T>> {}! type ConstObject<T> = {! readonly [P in keyof T]: Const<T[P]>! };! ! type Const<T> = T extends Primitive! ? T! : T extends ConstArray<any>! ? T! : T extends (infer R)[]! ? ConstArray<R>! : T extends object ? ConstObject<T> : T;!
  2. type Mutable<T> = T extends Primitive! ? T! : T

    extends MutableArray<any>! ? T! : T extends (infer R)[]! ? MutableArray<R>! : T extends ConstArray<infer A>! ? MutableArray<A>! : T extends object ? MutableObject<T> : T;! ! interface MutableArray<T> extends Array<Mutable<T>> {}! ! type MutableObject<T> = {! -readonly [P in keyof T]: Mutable<T[P]>! };!
  3. interface HumanEntityWriter extends Writer<HumanEntity> {! updateName(name: string): void;! updateAge(age: number):

    void;! }! ! interface HumanEntity extends Writable<HumanEntityWriter> {! name: string;! age: number;! }!
  4. import produce from 'immer';! function mutate<T extends Writable<U>, U>(! entity:

    T, ! callback: (writer: U) => void! ) {! produce(entity, draft => {! callback({! ...entity._writer,! _target: entity! });! });! }!