LE

A

PLAY

GaME

@phenomnomnominal 2022

@phenomnomnominal 2022

Sign

here

in

@phenomnomnominal 2022

HELLO!?

@phenomnomnominal 2022

What's going on?

@phenomnomnominal 2022

I'm CrAig

@phenomnomnominal 2022

@phenomnomnominal 2022

&

ex

in

type A

te

nd

s

fer

= B ?

C :

D

@phenomnomnominal 2022

@phenomnomnominal 2022

UnKno

inter

wn

face

ty

class

number

null

|

pe

@phenomnomnominal 2022

string

Date

boolean

Thingie

@phenomnomnominal 2022

const name: string = 'Craig';

Cannot Assign String to Number

const isKidnapped: boolean = true;

const timeRemaining: string = 18;

@phenomnomnominal 2022

const name: string = 'Craig';

CAN ASSIGN ANYTHING TO ANY

const isKidnapped: boolean = true;

const timeRemaining: any = 18;

@phenomnomnominal 2022

any

ANY IS A

TOP TYPE

string

Date

boolean

Thingie

@phenomnomnominal 2022

const isDead: boolean = true;

CAN ASSIGN ANYTHING TO unknown

const isAlive: boolean = false;

const timeRemaining: unknown = 18;

@phenomnomnominal 2022

any

string

Date

boolean

Thingie

Unknown IS Also A

TOP TYPE

unknown

@phenomnomnominal 2022

any

never

unknown

@phenomnomnominal 2022

Can't Assign anything to never

const nada: never = true;

const nope: never = null;

const nothing: never = 'Eighteen';

const nej: never = [];

const nein: never = () => ({});

@phenomnomnominal 2022

any

never

Never IS THE

Bottom TYPE

unknown

@phenomnomnominal 2022

@phenomnomnominal 2022

@phenomnomnominal 2022

We got it!

@phenomnomnominal 2022

@phenomnomnominal 2022

asserts

PASS =

input

is

PASS

`${string}

_${string}`

in

string

|

number

|

Null

=

@phenomnomnominal 2022

@phenomnomnominal 2022

never

any

unknown

@phenomnomnominal 2022

const input: unknown = 'HELP';

function shout (input: string): string {

  return `${input}!`;

}

shout(input);

Can't Assign unknown to string

@phenomnomnominal 2022

string

unknown

@phenomnomnominal 2022

if (typeof input === 'string') {
 

}

  shout(input);

Input is definitely a string

const input: unknown = 'HELP';

function shout (input: string): string {

  return `${input}!`;

}

@phenomnomnominal 2022

string

"HELP" | "PLEASE" | "SAVE US"

@phenomnomnominal 2022

function isHelp (input: unknown): input is Help {
 
const HELPS = ['HELP', 'PLEASE', 'SAVE US'];

  return HELPS.includes(input as Help);

}

SPecial Type Guard Syntax

type Help = 'HELP' | 'PLEASE' | 'SAVE US';

@phenomnomnominal 2022

Input is definitely a valid string

if (isHelp(input)) {

  shout(input);

}

const input: unknown = 'HELP';

type Help = 'HELP' | 'PLEASE' | 'SAVE US';

function isHelp (input: unknown): input is Help {
 
const HELPS = ['HELP', 'PLEASE', 'SAVE US'];

  return HELPS.includes(input as Help);

}

@phenomnomnominal 2022

string

`${string}!`

@phenomnomnominal 2022

type Exclamation = `${string}!`;

special assertion guard syntax

function validate (input: unknown):                              {

  if (typeof input !== 'string' || !input.endsWith('!')) {
   
throw new Error();
  }

}

                                    asserts input is Exclamation

@phenomnomnominal 2022

Input is definitely an Exclamation

validate(input);

 

shout(input);

type Exclamation = `${string}!`;

const input: unknown = 'HELP!';

function validate (input: unknown): asserts input is Exclamation {

  if (typeof input !== 'string' || !input.endsWith('!')) {
   
throw new Error();
  }

}

@phenomnomnominal 2022

type Scream = Uppercase<Exclamation>;

type GoodPassword = `${Scream}_${Whisper}`;

type Whisper = Lowercase<Exclamation>;

'A!_a!' | 'AA!_a!' | 'AAA!_aaa!' | 'AAAA!_aaaa! | 'AAAAA!_aaaaa!' | 'AAAAAA!_aaaaaa!' | ...

type Exclamation = `${string}!`;

@phenomnomnominal 2022

@phenomnomnominal 2022

@phenomnomnominal 2022

@phenomnomnominal 2022

ty

prop

peof

in

key

erty

<>

of

[index: string]

@phenomnomnominal 2022

Array<Item>

Promise<Resolved>

Uppercase<`${string}!`>;

Intrinsic string manipulation type

@phenomnomnominal 2022

type VictimName = string;
type VictimNames = Array<string>

type Help = 'HELP' | 'PLEASE' | 'SAVE US'

type Exclamation = `${string}!`;

@phenomnomnominal 2022

const status = {
  'Ana': 'ungrateful',
  'Rhubarb': 'grateful',
  'Chau': 'ungrateful',
  'Jeff': 'ungrateful',
  'Santosh': 'ungrateful',
  'Sherry': 'ungrateful'
};

type VictimStatus = Record<string, string>;

@phenomnomnominal 2022

type VictimStatus = {
  [key:
VictimName]: string;
}

type MikeStatus = VictimStatus['Mike']; // string

@phenomnomnominal 2022

type MakeGrateful<Victims> = {
    [Name in keyof
Victims]: 'grateful'
}

type Grateful = MakeGrateful<VictimStatus>;

type CraigStatus = Grateful['Craig']; // 'grateful'

type VictimStatus = {
  [key:
VictimName]: string;
}

@phenomnomnominal 2022

typefunction MakeGrateful (input) {


 


 


}

This is imaginary syntax!

    type output = {};
 

        output[name] = 'grateful';

    return output;


    for (name in input) {


    }
 

@phenomnomnominal 2022

type MakeMemorial<Victims> = {
  [Name in keyof
Victims as `❤️ ${Name}`]: Victims[Name]
}

const LAST_WORDS = {

  'Kirk': 'Plz',
  'Spivey': 'My god, what have I done?',
  'Erik': 'Will I get brutally murdered?',
  'Srashti': 'Why not 😁',
  'Katerina': '🐈'
}

define the new property

Lookup the type with the original name

@phenomnomnominal 2022

typefunction MakeMemorial (input) {


 



 

}

Lookup the type with the original name

define the new property

 


 

                            = input[name];

 

 


    for (name in input) {


    }
 

 

    type output = {};
 

        output[`❤️${name}`]

    return output;

@phenomnomnominal 2022

type Memorials = MakeMemorial<typeof LAST_WORDS>;

const LAST_WORDS = {

  'Kirk': 'Plz',
  'Spivey': 'My god, what have I done?',
  'Erik': 'Will I get brutally murdered?',
  'Srashti': 'Why not 😁',
  'Katerina': '🐈'
} as const;

Use typeof to Get a type from a POJO

Use specific string types

@phenomnomnominal 2022

type Memorials = MakeMemorial<typeof LAST_WORDS>;

const LAST_WORDS = {

  'Kirk': 'Plz',
  'Spivey': 'My god, what have I done?',
  'Erik': 'Will I get brutally murdered?',
  'Srashti': 'Why not 😁',
  'Katerina': '🐈'
} as const;

type KirkMemorial = Memorials['❤️ Kirk']; // 'Plz'

look up the type with the mapped key

type KirkMemorial = Memorials['Kirk'];
// Error: Property "Kirk" does not exist

@phenomnomnominal 2022

type MappedType<A> = {
  [B in keyof A
 as C]: D
}

 A: Input Type

 B: Union of KEY names

 C: Mapped Key

 D: Mapped TYpe

@phenomnomnominal 2022

@phenomnomnominal 2022

@phenomnomnominal 2022

@phenomnomnominal 2022

@phenomnomnominal 2022

@phenomnomnominal 2022

@phenomnomnominal 2022

_!#J?:>

_!#7?:>

_!#3?:>

_!#E?:>

in

A ext

fer

 B ?

C :

D

ends

Para

meters

extends

@phenomnomnominal 2022

type A extends B ? C : D

@phenomnomnominal 2022

type ConditionalType<A> = A extends B ? C : D