Last active
May 31, 2018 13:05
-
-
Save x7c1/d7cb8fa9d14c888ede33cba2f9454da3 to your computer and use it in GitHub Desktop.
example of nominal typing by TypeScript
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
| const showHtml = (html: Html) => console.log(`${html}`); | |
| const html = Html("tagged html sample"); | |
| showHtml(html); // tagged html sample | |
| const css = Css("tagged css sample"); | |
| showHtml(css); | |
| /* | |
| error TS2345: Argument of type 'TaggedString<"css">' is not assignable to parameter of type 'TaggedString<"html">'. | |
| Types of property 'type' are incompatible. | |
| Type '"css"' is not assignable to type '"html"'. | |
| */ |
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
| export type Tagged<A extends string> = { | |
| typeTag: A; | |
| }; | |
| export type Tagger<A, RAW> = (raw: RAW) => A; | |
| export const TaggerFrom = <RAW>() => <X>(f: (r: RAW) => X) => { | |
| return <A extends string>(typeTag: A): Tagger<Tagged<A> & X, RAW> => { | |
| return (raw: RAW) => Object.assign(f(raw), { typeTag }); | |
| }; | |
| }; | |
| export type StringTagged<A extends string> = Tagged<A> & { | |
| toString: () => string; | |
| }; | |
| export type StringTagger<A> = Tagger<A, string>; | |
| export const StringTagger = TaggerFrom<string>()(raw => ({ | |
| toString: () => raw, | |
| })); | |
| export type Css = StringTagged<"css">; | |
| export const Css: StringTagger<Css> = StringTagger("css"); | |
| export type Html = StringTagged<"html">; | |
| export const Html: StringTagger<Html> = StringTagger("html"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment