Generate Explicit Interface code from Inferred TypeScript Interface

Viewed 98

Let's say, I have a code snippet:

const todo = {name: "Learn Some TS", isDone: true}

How can I automatically generate the following:

interface TodoInterface {
    name: string
    isDone: Boolean
}

Looking for any tools where I can get the interface from code snippets. It doesn't necessarily have to solve this exact scenario.

1 Answers

In the IDEs I use (VSCode and The TypeScript Playground), I hover the pointer over the value whose type I want to capture. This brings up IntelliSense quick info describing the type, and you can copy and paste that.

For

const todo = { name: "Learn Some TS", isDone: true }

The provided info looks like this

/* const todo: {
    name: string;
    isDone: boolean;
} */

which can be copied, pasted, and modified to give you

interface TodoInterface {
  name: string;
  isDone: boolean;
}

Supplemental screen capture demo:

Screen capture of copy/pasting IntelliSense quick info


Note that your compiler options may end up truncating long types. For example, imagine you have this type:

type SomeFiltered<T extends any[]> =
  T extends [infer F, ...infer R] ? [F, ...SomeFiltered<R>] | SomeFiltered<R> : []

It takes a tuple type and produces a union of all possible filtered versions of it. Since each element can either be present or absent, you end up turning a tuple of elements into a union of 2 tuples. That's a lot. So this

type LongType = SomeFiltered<["A", "B", "C", "D", "E"]>

can be expected to have 32 union members. With default compiler options, you will not see the full type with IntelliSense:

/*
type LongType = [] | ["A", "B", "C", "D", "E"] | ["B", "C", "D", "E"] | ["C", "D", "E"] |
  ["D", "E"] | ["E"] | ["D"] | ["C"] | ["C", "E"] | ["C", "D"] | ["B"] | ["B", "D", "E"] |
  ["B", "E"] | ... 18 more ... | [...]
*/

See the ... 18 more ... and [...] truncations.

You can disable such truncation by enabling the --noErrorTruncation compiler flag. (It's a little bit of an unfortunate name, since it suppresses truncation of displayed type names everywhere, not just in error messages.) Then you get this:

/* with --noErrorTruncation=true
type LongType = ["A", "B", "C", "D", "E"] | ["B", "C", "D", "E"] | ["C", "D", "E"] | 
  ["D", "E"] | ["E"] | [] | ["D"] | ["C", "E"] | ["C"] | ["C", "D"] | ["B", "D", "E"] | 
  ["B", "E"] | ["B"] | ["B", "D"] | ["B", "C", "E"] | ["B", "C"] | ["B", "C", "D"] | 
  ["A", "C", "D", "E"] | ["A", "D", "E"] | ["A", "E"] | ["A"] | ["A", "D"] | 
  ["A", "C", "E"] | ["A", "C"] | ["A", "C", "D"] | ["A", "B", "D", "E"] | 
  ["A", "B", "E"] | ["A", "B"] | ["A", "B", "D"] | ["A", "B", "C", "E"] | 
  ["A", "B", "C"] | ["A", "B", "C", "D"]
*/

Playground link to code

Related