Skip to content

The infer keyword

Daisho Komiyama edited this page Nov 1, 2022 · 1 revision

The infer keyword is an important tool to solve this problem — it lets us extract and obtain type information from larger types.

Let’s simplify the problem we aim to solve, by working with a much simpler class:

class FruitStand {
  constructor(fruitNames: string[]) {}
}

What we want is some kind of thing, where FruitStand is our input, and string[] is our result. Here’s how we can make that happen:

type ConstructorArg<C> = C extends {
  new (arg: infer A, ...args: any[]): any
}
  ? A
  : never

let fruits: ConstructorArg<typeof FruitStand>
// ^ let fruits: string[]

class WebpackCompiler {
  constructor(options: {
    amd?: false | { [index: string]: any }
    bail?: boolean
    cache?:
      | boolean
      | {
          maxGenerations?: number
          type: "memory"
        }
    context?: string
    dependencies?: string[]
    devtool?: string | false
    entry?: string
    chunkLoading?: string | false
    dependOn?: string | string[]
    layer?: null | string
    runtime?: string
    wasmLoading?: string | false
    externalsType?:
      | "var"
      | "module"
      | "assign"
      | "this"
      | "window"
      | "self"
      | "global"
      | "commonjs"
      | "commonjs2"
      | "commonjs-module"
      | "amd"
      | "amd-require"
      | "umd"
      | "umd2"
      | "jsonp"
      | "system"
      | "promise"
      | "import"
      | "script"
 
    ignoreWarnings?: (
      | RegExp
      | {
          file?: RegExp
 
          message?: RegExp
 
          module?: RegExp
        }
    )[]
    loader?: { [index: string]: any }
    mode?: "development" | "production" | "none"
    name?: string
    parallelism?: number
    profile?: boolean
    recordsInputPath?: string | false
    recordsOutputPath?: string | false
    recordsPath?: string | false
    stats?:
      | boolean
      | "none"
      | "summary"
      | "errors-only"
      | "errors-warnings"
      | "minimal"
      | "normal"
      | "detailed"
      | "verbose"
    target?: string | false | string[]
    watch?: boolean
  }) {}
}

let compilerOptions: ConstructorArg<typeof WebpackCompiler>
// ^ let compilerOptions: {
    amd?: false | {
        [index: string]: any;
    } | undefined;
    bail?: boolean | undefined;
    cache?: boolean | {
        maxGenerations?: number | undefined;
        type: "memory";
    } | undefined;
    context?: string | undefined;
    ... 20 more ...;
    watch?: boolean | undefined;
}
Clone this wiki locally