Symbol

const userid = Symbol('userid')

export class User {
  id: {
    [userid]: true;
    value: string
  }

  constructor(id: string) {
    this.id = {
      [userid]: true,
      value: id
    }
  }
}

const postid = Symbol('postid')

export class Post {
  id: {
    [postid]: true; // Branding
    value: string
  }

  constructor(id: string) {
    this.id = {
      [postid]: true,
      value: id
    }
  }
}



const user = new User('1234')
const post = new Post('5678')

user.id = post.id // Property '[userid]' is missing in type '{ value: string; [postid]: true; }' but required in type '{ value: string; [userid]: true; }'


/** Private scope */
export const TYPE_A = Symbol('TYPE_A')
export const TYPE_B = Symbol('TYPE_B')

type ObjA = {
  $$type: typeof TYPE_A
  objectAProp: string
}

type ObjB = {
  $$type: typeof TYPE_B
  objectBProp: string
}

type AllObj = ObjA | ObjB // discriminated union




function run(obj: AllObj) {

  console.log(obj.objectAProp) 
  // Property 'objectAProp' does not exist on type 'AllObj'.
  // Property 'objectAProp' does not exist on type 'ObjB'. (typescript)
  switch (obj.$$type) {
      case TYPE_A:
        // obj is ObjA
        console.log(obj.objectAProp) // OK
        break
      case TYPE_B:
        // obj is ObjB
        obj
        break
  }
}

Last updated

Was this helpful?