mietzekotze
mietzekotze

Reputation: 303

How to infer generic values in interfaces like in functions

Typescript has this nice feature, where when given the types

type Foo = "foo"
type Bar = "bar"
type FooBar = Foo | Bar;
type IfFooThenBar<T extends FooBar> = T extends Foo ? Bar :
  T extends Bar ? Foo : never;

and a function

function ifFooThenBar<T extends FooBar>(fooOrBar: T, barOrFoo: IfFooThenBar<T>): void

it infers T from the functions parameter list and applies it to IfFooThenBar<T> and narrows down the potential candidates for the parameter, so that ifFooThenBar("foo", "foo") will not compile.

Is there a similiar mode for interfaces where this works:

interface IIfFooThenBar<T extends FooBar> {
  fooOrBar: T
  barOrFoo: IfFooThenBar<T>
}

const a: IIfFooThenBar = {
  fooOrBar: "foo",
  barOrFoo: "foo" // this should result in an error
}

Upvotes: 0

Views: 33

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250366

Typescript does not have partial inference for variables, you need to use a function to infer the type parameter of the interface.

The shortest way to do it is with an IIFE:

type Foo = "foo"
type Bar = "bar"
type FooBar = Foo | Bar;
type IfFooThenBar<T extends FooBar> = T extends Foo ? Bar :
    T extends Bar ? Foo : never;



interface IIfFooThenBar<T extends FooBar> {
    fooOrBar: T
    barOrFoo: IfFooThenBar<T>
}

const a = (<T extends FooBar>(o: IIfFooThenBar<T>) => o)({
    fooOrBar: "foo",
    barOrFoo: "foo" // err
})

Upvotes: 1

Related Questions