03:56
<Jack Works>
i'd love to see some examples that feel javascripty

I'll show some code I found in our product source. You may argue TypeScript is not javascripty but it's a big part you cannot unsee in the JS community

type Action =
    | { type: 'SET_ACCOUNT_TYPE', accountType: BackupAccountType }
    | { type: 'TO_STEP', step: RestoreStep }
    | { type: 'SET_EMAIL', form: Partial<RestoreState['emailForm']> }
    | { type: 'SET_PHONE', form: Partial<RestoreState['phoneForm']> }
    | { type: 'SET_VALIDATION' }
    | { type: 'SET_BACKUP_INFO', info: BackupFileInfo }
    | { type: 'SET_BACKUP_SUMMARY', summary: BackupSummary, backupDecrypted: string }
    | { type: 'SET_PASSWORD', password: string }
    | { type: 'SET_LOADING', loading: boolean }

function restoreReducer(state: RestoreState, action: Action) {
    return produce(state, (draft) => {
        switch (action.type) {
            case 'SET_ACCOUNT_TYPE':
                // ...
            case 'NEXT_STEP':
                // ...
            case 'TO_STEP':
                // ...
        }
    })
}
dispatch({ type: 'SET_ACCOUNT_TYPE', accountType: 'email' })
03:56
<Jack Works>
I wrote this pattern a lot. My co-workers also.
03:57
<ljharb>
nah TS code isn’t necessarily un-JavaScripty :-) not making that claim.
03:57
<ljharb>
so, that kind of switch usage is very common. That’s using a tagged union where the tag could be a primitive enum.
03:58
<Jack Works>
well, the important thing here is that the tag is always bind with a known-shaped structure
03:59
<Jack Works>
I'll rewrite this code with primitive enum and ADT enum
04:02
<Jack Works>

Primitive

enum Action {
    SET_ACCOUNT_TYPE,
    TO_STEP,
    SET_EMAIL,
    SET_PHONE,
    SET_VALIDATION,
    SET_BACKUP_INFO,
    SET_BACKUP_SUMMARY,
    SET_PASSWORD,
    SET_LOADING,
}
type Action =
    | { type: Action.SET_ACCOUNT_TYPE, accountType: BackupAccountType }
    | { type: Action.TO_STEP, step: RestoreStep }
    | { type: Action.SET_EMAIL, form: Partial<RestoreState['emailForm']> }
    | { type: Action.SET_PHONE, form: Partial<RestoreState['phoneForm']> }
    | { type: Action.SET_VALIDATION }
    | { type: Action.SET_BACKUP_INFO, info: BackupFileInfo }
    | { type: Action.SET_BACKUP_SUMMARY, summary: BackupSummary, backupDecrypted: string }
    | { type: Action.SET_PASSWORD, password: string }
    | { type: Action.SET_LOADING, loading: boolean }

function restoreReducer(state: RestoreState, action: Action) {
    return produce(state, (draft) => {
        match(action) {
            when { type: Action.SET_ACCOUNT_TYPE, let accountType }: expr,
            when { type: Action.SET_EMAIL, let form }: expr,
            when { type: Action.TO_STEP, let step }: expr,
        }
    })
}
dispatch({ type: 'SET_ACCOUNT_TYPE', accountType: 'email' })
04:04
<Jack Works>

ADT

enum Action {
    SET_ACCOUNT_TYPE(accountType: BackupAccountType),
    TO_STEP(step: RestoreStep),
    SET_EMAIL(form: Partial<RestoreState['emailForm']>),
    SET_PHONE(form: Partial<RestoreState['phoneForm']>),
    SET_VALIDATION,
    SET_BACKUP_INFO(info: BackupFileInfo),
    SET_BACKUP_SUMMARY(summary: BackupSummary, backupDecrypted: string),
    SET_PASSWORD(password: string),
    SET_LOADING(loading: boolean),
}

function restoreReducer(state: RestoreState, action: Action) {
    return produce(state, (draft) => {
        match(action) {
            when Action.SET_ACCOUNT_TYPE(let accountType): expr,
            when Action.SET_EMAIL(let form): expr,
            when Action.TO_STEP(let step): expr,
        }
    })
}
dispatch(Action.SET_ACCOUNT_TYPE('email'))
04:08
<Jack Works>
adt can reduce a lot of redundant code in this pattern. make code more dense and let people write more semantic code
04:12
<ljharb>
What about that code requires the enum values to not be strings?
04:13
<Jack Works>
What about that code requires the enum values to not be strings?
sorry can you rephrase? I did not understand the meaning
04:14
<ljharb>
i mean that seems like a nicer sugar for the non-enum version of the code - where the tags are still strings, just better typed.
04:16
<Jack Works>
yes, if we remove the typescript part, it looks like just a small syntax sugar (but also with all performance benefits that Ron mentioned)
04:16
<Jack Works>
with typescript this feature is a huge improve
04:17
<ljharb>
right, and I’m super on board for that. but i don’t see what “adt” adds there nor why enum values need to be objects
04:17
<ljharb>
every enum proposal so far has satisfied that code’s need, which is a good thing
16:44
<ljharb>
(note: there was a typo in the TOC, but then i realized having a TOC is redundant because github auto-makes one on every markdown file, so i removed it)