Log in to GraphQL EditorGet started
Advanced typescript tutorial - conditional types
Artur

Artur Czemiel

12/11/2018

Advanced typescript tutorial - conditional types

Hello, This is the second article of the advanced typescript tutorial series. Today I'll cover the basic usage of

extends

keyword and conditional types. How does conditional type looks like?

type StringOrArray<T> = T extends string[] ? 'array' : T extends string ? 'string' : never
const a:string = "hello"
const b:string[] = ["hello","world"]
const c:number = 1

const d:StringOrArray<typeof a> = "string"
const e:StringOrArray<typeof b> = "array"
let f:StringOrArray<typeof c> 

So let's analyze this code:

  1. We check if our generic Type is a string array
  2. If it is array make type as string constant 'array'
  3. If it does not check the type. If it is string make type as string constant 'string'
  4. Else the type is never

To be the truth this code is useless but can give you some scope how extends keyword works. Next example will be a real-world example where we determine the type of the form field to give the user correct options.

type FieldType = "string" | "float" | "date"

type BaseField = {
    name:string
}

type Field<T extends FieldType> = BaseField & {
    value: T extends "string" ? string : T extends "float" ? number : T extends "date" ? Date : never
}

const stringField:Field<"string"> = {
    name:"myfield",
    value:"aaa"
}
const floatField:Field<"float"> = {
    name:"myfield",
    value:1.0
}

const dateField:Field<"date"> = {
    name:"myfield",
    value: new Date()
}

This is a little bit more advanced. What's going on with FieldType? It just checks the string converted to generic type to return correct type.


type FieldType = "string" | "float" | "date";
type BaseFieldExtended = {
  name: string;
  type: FieldType;
};
const FieldExtended = <T extends BaseFieldExtended>(
  baseField: T & {
    value: T["type"] extends "string"
      ? string
      : T["type"] extends "date"
      ? Date
      : T["type"] extends "float"
      ? number
      : never;
  }
) => baseField;

FieldExtended({
  name: "a",
  type: "string",
  value: "bbb"
});

FieldExtended({
  name: "a",
  type: "float",
  value: 12
});

FieldExtended({
  name: "a",
  type: "date",
  value: new Date()
});

And this is what typescript is made for. To provide complicated autocompletion stuff :). Wait for the next series of advanced typescript tutorial.

Check out our other blogposts

Zustand - react state management made easy
Michał Tyszkiewicz
Michał Tyszkiewicz
Zustand - react state management made easy
5 min read
over 1 year ago
Eleventy components woes
Michał Tyszkiewicz
Michał Tyszkiewicz
Eleventy components woes
8 min read
about 1 year ago
Code Academy - How to visualize your GraphQL schema?
Tomek Poniatowicz
Tomek Poniatowicz
Code Academy - How to visualize your GraphQL schema?
3 min read
over 5 years ago

Ready for take-off?

Elevate your work with our editor that combines world-class visual graph, documentation and API console

Get Started with GraphQL Editor