Last active
December 14, 2017 20:10
-
-
Save geovanisouza92/39f76f2f9e80ef9c1a42ecb2b625b4ec to your computer and use it in GitHub Desktop.
--strictFunctionTypes generates errors with generic functions
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 Direction = keyof IDirectionOptions; | |
interface IDirectionOptions { | |
"horizontal": { foo: number; }; | |
"vertical": { bar: string; }; | |
"diagonal": { baz: boolean; }; | |
} | |
// This structure works | |
type FnOk<D extends Direction> = () => ResultOk<D>; | |
type ResultOk<D extends Direction> = | |
{ kind: "invalid", err: Error } | |
| { kind: "valid", data: IDirectionOptions[D] } | |
; | |
function horizontalOk(): ResultOk<"horizontal"> { | |
return { kind: "valid", data: { foo: 123 } }; | |
}; | |
function verticalOk(): ResultOk<"vertical"> { | |
if (Math.random() > 0.5) { | |
return { kind: "valid", data: { bar: "foo" } }; | |
} | |
return { kind: "invalid", err: new Error("LOL") }; | |
} | |
const horizontalOkConst: FnOk<"horizontal"> = horizontalOk; | |
const verticalOkConst: FnOk<"vertical"> = verticalOk; | |
function selectOk<D extends Direction>(direction: Direction): FnOk<D> { | |
switch (direction) { | |
case "horizontal": return horizontalOk; | |
case "vertical": { | |
const v = verticalOk(); | |
if (v.kind === "valid") { | |
v.data.bar; | |
} | |
return verticalOk; | |
} | |
case "diagonal": return () => ({ kind: "invalid", err: new Error("lol") }); | |
} | |
} | |
// This structure doesn't | |
type FnErr<D extends Direction> = () => ResultErr<D>; | |
type ResultErr<D extends Direction> = | |
{ kind: "invalid", err: Error } | |
| { kind: "valid", data: IData<D> } | |
; | |
interface IData<D extends Direction> { | |
value: IDirectionOptions[D]; | |
} | |
function horizontalErr(): ResultErr<"horizontal"> { | |
return { kind: "valid", data: { value: { foo: 123 } } }; | |
}; | |
function verticalErr(): ResultErr<"vertical"> { | |
if (Math.random() > 0.5) { | |
return { kind: "valid", data: { value: { bar: "foo" } } }; | |
} | |
return { kind: "invalid", err: new Error("LOL") }; | |
} | |
const horizontalErrConst: FnErr<"horizontal"> = horizontalErr; | |
const verticalErrConst: FnErr<"vertical"> = verticalErr; | |
function selectErr<D extends Direction>(direction: Direction): FnErr<D> { | |
switch (direction) { | |
case "horizontal": return horizontalErr; // Error here | |
case "vertical": { | |
const v = verticalErr(); | |
if (v.kind === "valid") { | |
v.data.value.bar; | |
} | |
return verticalErr; // Error here | |
} | |
case "diagonal": return () => ({ kind: "invalid", err: new Error("lol") }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment