Home > Software design >  How to write generic type for literal name in typescript?
How to write generic type for literal name in typescript?

Time:11-24

I am writing d.ts file for js-data library, and the following code can simplify my demands:

interface Note {
  id: number,
  title: string,
  text: string
}
interface Comment {
  id: number,
  content: string,
  noteId: number
}

function create(name: 'note', attrs: Note): Note
function create(name: 'comment', attrs: Comment): Comment
// ... and so on

Based on above definitions, I can invoke functions for type checks:

create('note', { id: 1, title: 'note title', body: 'note body' }) // work
create('comment', { id: 11, content: 'comment content', noteId: 1 }) // work

create('nott', ...) // not work, there is a spelling mistake
create('note', { id: 11, content: 'comment content', noteId: 1 }) // not work, attrs should be type Note

Though I can write as many as possible overloading functions like above, but the work is too tedious. Is there any way to simplify such work with generics?

CodePudding user response:

type Attrs = {
  note: Note
  comment: Comment
}

type AttrName = keyof Attrs

declare function create<T extends AttrName>(name: T, attrs: Attrs[T]): Note

playground link

  • Related