Skip to content

Instantly share code, notes, and snippets.

@jonwingfield
Last active January 4, 2020 19:57
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 jonwingfield/efbe9367eb55ae03d509dca996dc701c to your computer and use it in GitHub Desktop.
Save jonwingfield/efbe9367eb55ae03d509dca996dc701c to your computer and use it in GitHub Desktop.
Conditional Types
// From https://artsy.github.io/blog/2018/11/21/conditional-types-in-typescript/
// Includes extra exercises.
type Action =
| {
type: "INIT"
}
| {
type: "SYNC"
}
| {
type: "LOG_IN"
emailAddress: string
}
| {
type: "LOG_IN_SUCCESS"
accessToken: string
}
type ActionType = Action["type"]
type OnlyWithoutType<T> = T extends any ?
{} extends Omit<T, 'type'> ? T : never
: never;
type OnlyWithType<T> = T extends any ?
{} extends Omit<T, 'type'> ? never : T
: never;
type EmptyActions = OnlyWithoutType<Action>;
type EmptyActionTypes = EmptyActions['type'];
type CompexActions = OnlyWithType<Action>;
type ComplexActionTypes = CompexActions['type'];
//type X = Omit<
declare function dispatch<T extends EmptyActionTypes>(type: T) : void;
declare function dispatch<T extends ComplexActionTypes>(
type: T,
args: ExtractActionParameters<Action, T>
): void
type ExcludeTypeKey<K> = K extends "type" ? never : K
type ExcludeTypeField<A> = { [K in ExcludeTypeKey<keyof A>]: A[K] }
type OnlyTypeKey<K> = K extends "type" ? K : never;
type ExtractActionParameters<A, T> = A extends { type: T }
? ExcludeTypeField<A>
: never
// All clear! :)
dispatch("LOG_IN_SUCCESS", {
accessToken: "038fh239h923908h"
})
dispatch("LOG_IN_SUCCESS", {
// Type Error! :)
badKey: "038fh239h923908h"
})
// Type Error! :)
dispatch("BAD_TYPE", {
accessToken: "038fh239h923908h"
})
// Works!
dispatch("INIT")
// Type Error! :)
dispatch("INIT", {})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment