From 6b1c91b520a81d2442a28b4d29361eb6aece584e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 11 Sep 2015 19:15:43 -0700 Subject: [PATCH] Added tests. --- .../overloadsWithTypePredicates01.ts | 52 +++++++++++++++++++ .../overloadsWithTypePredicates02.ts | 52 +++++++++++++++++++ .../overloadsWithTypePredicates03.ts | 42 +++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 tests/cases/conformance/functions/overloadsWithTypePredicates01.ts create mode 100644 tests/cases/conformance/functions/overloadsWithTypePredicates02.ts create mode 100644 tests/cases/conformance/functions/overloadsWithTypePredicates03.ts diff --git a/tests/cases/conformance/functions/overloadsWithTypePredicates01.ts b/tests/cases/conformance/functions/overloadsWithTypePredicates01.ts new file mode 100644 index 00000000000..244b4d03a11 --- /dev/null +++ b/tests/cases/conformance/functions/overloadsWithTypePredicates01.ts @@ -0,0 +1,52 @@ +// @declaration: true + +/** + * A makeshift string enum. + */ +namespace EventType { + export type Click = string & { _fooTag: any }; + export const Click = "Click"; + + export type KeyDown = string & { _barTag: any }; + export const KeyDown = "KeyDown"; +} + +/** + * The all-encompassing type for our makeshift enum. + */ +type EventType = EventType.Click + | EventType.KeyDown; + + +interface BaseEvent { + type: EventType; +} + +interface ClickEvent extends BaseEvent { + type: EventType.Click; + x: number; + y: number; +} + +interface KeyDownEvent extends BaseEvent { + type: EventType.KeyDown; + keyCode: number; +} + +function isActionType(action: BaseEvent, type: EventType.Click): action is ClickEvent; +function isActionType(action: BaseEvent, type: EventType.KeyDown): action is KeyDownEvent; +function isActionType(action: BaseEvent, type: EventType): action is BaseEvent; +function isActionType(action: BaseEvent, type: EventType) { + return action.type === type; +} + +let handleAction = (action: BaseEvent) => { + if (isActionType(action, EventType.Click)) { + let foo = action.x; + let bar = action.y; + } + + if (isActionType(action, EventType.KeyDown)) { + let bar = action.keyCode; + } +} diff --git a/tests/cases/conformance/functions/overloadsWithTypePredicates02.ts b/tests/cases/conformance/functions/overloadsWithTypePredicates02.ts new file mode 100644 index 00000000000..1365334acf5 --- /dev/null +++ b/tests/cases/conformance/functions/overloadsWithTypePredicates02.ts @@ -0,0 +1,52 @@ +// @declaration: true + +interface Nil { +} + +interface Cons { + value: T; + next: List; +} + +type List = Cons | Nil; +const nil: Nil = {}; +function cons(value: T, next: List) { + return { value, next }; +} + +function hasElements(list: Cons): list is Cons; +function hasElements(list: List): list is Cons; +function hasElements(list: List): list is Cons { + return !!(list as Cons).next; +} + +function isEmpty(list: Nil): list is Nil; +function isEmpty(list: List): list is Nil; +function isEmpty(list: List): boolean { + return !isEmpty(list); +} + +let listA = cons(1, cons(2, cons(3, nil))); +let listB = nil; +let listC: List = listA || listB; + +if (isEmpty(listA)) { + let a = listA; +} +else { + let a = listA; +} + +if (hasElements(listC)) { + let { value } = listC; +} +else { + let myNil: Nil = listC; +} + +if (hasElements(listB)) { + let somehowCons: Cons = listB; +} +else { + let myNil: Nil = listB; +} \ No newline at end of file diff --git a/tests/cases/conformance/functions/overloadsWithTypePredicates03.ts b/tests/cases/conformance/functions/overloadsWithTypePredicates03.ts new file mode 100644 index 00000000000..0a8f035578c --- /dev/null +++ b/tests/cases/conformance/functions/overloadsWithTypePredicates03.ts @@ -0,0 +1,42 @@ +// @declaration: true + +function is(x: any, type: "number"): x is number; +function is(x: any, type: "string"): x is string; +function is(x: any, type: "boolean"): x is boolean; +function is(x: any, type: string): x is (number | boolean | string); +function is(x: any, type: string): boolean { + if (["string", "number", "boolean"].indexOf(type) >= 0) { + return typeof x === type; + } + + return false; +} + +declare function myRand(): boolean; + +let strNumOrBool: string | number | boolean; + +if (myRand()) { + strNumOrBool = "abc"; +} +else if (myRand()) { + strNumOrBool = 100; +} +else { + strNumOrBool = true; +} + +if (is(strNumOrBool, "number")) { + let num = strNumOrBool; + num *= 100; +} + +if (is(strNumOrBool, "string")) { + let str = strNumOrBool; + str = str.slice(); +} + +if (is(strNumOrBool, "boolean")) { + let bool = strNumOrBool; + bool = bool || bool && bool; +} \ No newline at end of file