Last active
July 23, 2019 03:30
-
-
Save pzi/9d848f9442a08940dab2a0f1af52d94a to your computer and use it in GitHub Desktop.
TypeScript: Conditional types and discriminated unions & narrowing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Block = Important | Emphasis | Regular | |
type BK = Block['kind'] | |
type Important = { kind: 'important'; important: string } | |
type Emphasis = { kind: 'emphasis'; emphasis: string } | |
type Regular = { kind: 'text'; text: string } | |
type SmartOpts<T extends Block['kind']> = Extract<Block, { kind: T }> | |
type RegularOptions = SmartOpts<'text'> | |
declare function doBlock<T extends BK>(kind: T, opts: SmartOpts<T>): void | |
const importantOpts: Important = { kind: 'important', important: 'asdsda' } | |
const regularOpts: Regular = { kind: 'text', text: 'text' } | |
doBlock('important', importantOpts) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface CommonProps { | |
className?: string | |
} | |
interface KindOne extends CommonProps { | |
kind: 'button' | |
something: string | |
} | |
interface KindTwo extends CommonProps { | |
kind: 'bigger-button' | |
label: string | |
} | |
type Props = KindOne | KindTwo | |
export const Button: React.FC<Props> = (props) => { | |
if (props.kind=== 'button') { | |
// now you know | |
// props.label doesn't exist | |
} | |
if (props.kind === 'bigger-button') { | |
// and again | |
// props.label exists | |
} | |
} | |
function Test() { | |
const t1 = <Button kind='button' something='foobar' /> // OK | |
const t2 = <Button kind='bigger-button' something='foobar' /> // Not OK | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment