Skip to content

Instantly share code, notes, and snippets.

@bcherny
Last active January 13, 2020 01:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bcherny/3e4b87ab3a8328ddb4da249b7545bee0 to your computer and use it in GitHub Desktop.
Save bcherny/3e4b87ab3a8328ddb4da249b7545bee0 to your computer and use it in GitHub Desktop.

Proposal: Mirrored syntax at the type and value-levels

Motivation

Make it easier to express the operations we work with most often:

  • When modeling GraphQL types with Flow: Looking up the type of a field in a nested object type, where every field along the way is nullable and optional
  • When authoring React components: Looking up the type of a prop on another component that we compose, to directly expose it on our component too

Proposed features

  • Lookup types: A[B]
  • Null chaining for types: A?.B
// Objects
type A = {
  B?: {
    C?: number,
    D?: string
  }
}
type C1 = A.B?.C              // number | undefined
type C2 = A['B']?.['C']       // number | undefined
type C3 = A['B']?.['C' | 'D'] // number | string | undefined

// Arrays
type D = [number, string[]]
type E = D[1]                 // string[]

Currently:

// Objects
type A = {
  B?: {
    C?: number,
    D?: string
  }
}
type C1 = $ElementType<
  $NonMaybeType<
    $ElementType<A, 'B'>
  >,
  'C'
>                                  // number | undefined
type C3 = C1 | $ElementType<
  $NonMaybeType<
    $ElementType<A, 'B'>
  >,
  'D'
>                                  // number | string | undefined

// Arrays
type D = [number, string[]]
type E = $PropertyType<D, 1>       // string[]

Out of scope features, that are fun to consider

// Diff types

type A = ?number                   // number | null | undefined
type B = A - (null | undefined)    // number

// Non-maybe types

type A = ?number                   // number | null | undefined
type B = A!                        // number

// Function call types

type F = (A, B) => C               // (A, B) => C
type C = F(A, B)                   // C
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment