Files
test-repo/tests/union_new/__snapshots__/jsfmt.spec.js.snap
T

1929 lines
39 KiB
Plaintext

exports[`test issue-815.js 1`] = `
"/* @flow */
type T = A|B;
class U {};
declare var children: U;
(children: T|U);
class A {};
class B {};
type VirtualElement = Thunk|VirtualNode;
type Child = VirtualElement;
type Children = Array<Child>;
class Thunk {}
class VirtualNode {
children: Child|Children;
constructor(type, children/*:Children*/) {
this.children = children.length === 1 ? children[0] :
children;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
type T = A | B;
class U {}
declare var children: U;
(children: T | U);
class A {}
class B {}
type VirtualElement = Thunk | VirtualNode;
type Child = VirtualElement;
type Children = Array<Child>;
class Thunk {}
class VirtualNode {
children: Child | Children;
constructor(type, children: Children) {
this.children = (children.length === 1 ? children[0] : children);
}
}
"
`;
exports[`test issue-824.js 1`] = `
"import { B, C } from \"./issue-824-helper\";
type K = B | C;
type I = {
which(): number;
};
export default class A {
static foo(p: K): bool {
return false;
}
static bar(p: I & K): bool {
return this.foo(p);
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import { B, C } from \"./issue-824-helper\";
type K = B | C;
type I = { which(): number };
export default class A {
static foo(p: K): boolean {
return false;
}
static bar(p: I & K): boolean {
return this.foo(p);
}
}
"
`;
exports[`test issue-824-helper.js 1`] = `
"import A from \"./issue-824\";
export class B extends A {
which(): number {
return 1;
}
}
export class C extends A {
which(): number {
return 2;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import A from \"./issue-824\";
export class B extends A {
which(): number {
return 1;
}
}
export class C extends A {
which(): number {
return 2;
}
}
"
`;
exports[`test issue-1349.js 1`] = `
"/* @flow */
var bar: Array<{b: ?boolean, c: number} | {b: boolean}> = [
{b: true, c: 123},
{b: true}
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
var bar: Array<{ b: ?boolean; c: number } | { b: boolean }> = [
{ b: true, c: 123 },
{ b: true }
];
"
`;
exports[`test issue-1371.js 1`] = `
"function create(a: any): { type: \'B\', data: number } | { type: \'A\', data: string }
{
return {
type: \'A\',
data: a
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function create(
a: any
): { type: \"B\"; data: number } | { type: \"A\"; data: string } {
return { type: \"A\", data: a };
}
"
`;
exports[`test issue-1455.js 1`] = `
"/* @flow */
import type {Foobar} from \"./issue-1455-helper\"
function create(content: ?Foobar | String | Array<String>) {
}
function node(content: ?Foobar | String | Array<String>) {
create(content)
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
import type { Foobar } from \"./issue-1455-helper\";
function create(content: ?Foobar | String | Array<String>) {}
function node(content: ?Foobar | String | Array<String>) {
create(content);
}
"
`;
exports[`test issue-1455-helper.js 1`] = `
"/* @flow */
export class Foobar { }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
export class Foobar {}
"
`;
exports[`test issue-1462-i.js 1`] = `
"type Common = {
};
type A = Common & {
type: \'A\',
foo: number
};
type B = Common & {
type: \'B\',
foo: Array<number>
}
type MyType = A | B;
function print(x: number) {
console.log(x);
}
function printAll(val: MyType) {
print(val.foo); // <--- foo could be an array
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// <--- foo could be an array
type Common = {};
type A = Common & { type: \"A\"; foo: number };
type B = Common & { type: \"B\"; foo: Array<number> };
type MyType = A | B;
function print(x: number) {
console.log(x);
}
function printAll(val: MyType) {
print(val.foo);
}
"
`;
exports[`test issue-1462-ii.js 1`] = `
"type Common = {
};
type A = {
type: \'A\',
foo: number
} & Common;
type B = {
type: \'B\',
foo: Array<number>
} & Common;
type MyType = A | B;
function print(x: number) {
console.log(x);
}
function printAll(val: MyType) {
if (val.type === \'A\') {
print(val.foo);
} else {
val.foo.forEach(print);
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
type Common = {};
type A = { type: \"A\"; foo: number } & Common;
type B = { type: \"B\"; foo: Array<number> } & Common;
type MyType = A | B;
function print(x: number) {
console.log(x);
}
function printAll(val: MyType) {
if (val.type === \"A\") {
print(val.foo);
} else {
val.foo.forEach(print);
}
}
"
`;
exports[`test issue-1664.js 1`] = `
"/* @flow */
type DataBase = {
id: string,
name: string,
};
type UserData = DataBase & {
kind: \"user\",
};
type SystemData = DataBase & {
kind: \"system\",
}
type Data = UserData | SystemData;
const data: Data = {
id: \"\",
name: \"\",
kind: \"system\",
}
if (data.kind === \"system\") {
(data: SystemData);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
type DataBase = { id: string; name: string };
type UserData = DataBase & { kind: \"user\" };
type SystemData = DataBase & { kind: \"system\" };
type Data = UserData | SystemData;
const data: Data = { id: \"\", name: \"\", kind: \"system\" };
if (data.kind === \"system\") {
(data: SystemData);
}
"
`;
exports[`test issue-1759.js 1`] = `
"// @flow
type X = ({a:true} & {b:string}) | ({a:false} & {c:string});
//type X = {a:true, b:string} | {a:false, c:string}; // this works.
function hello(x:X): string {
if (x.a === true) return x.b; else return x.c;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
//type X = {a:true, b:string} | {a:false, c:string}; // this works.
type X = ({ a: true } & { b: string }) | ({ a: false } & { c: string });
function hello(x: X): string {
if (x.a === true)
return x.b;
else
return x.c;
}
"
`;
exports[`test issue-2232.js 1`] = `
"/* @flow */
declare type Entity<T> = {
id: T,
name: string
}
declare type StringEntity = Entity<string>
declare type Foo = StringEntity & {
bars: Object,
kind: 1
}
declare type EmptyFoo = StringEntity & {
bars: null,
kind: 2
}
function test(f: Foo| EmptyFoo) {
if (f.kind === 1) {
(f: Foo)
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
type Entity<T> = { id: T; name: string };
type StringEntity = Entity<string>;
type Foo = StringEntity & { bars: Object; kind: 1 };
type EmptyFoo = StringEntity & { bars: null; kind: 2 };
function test(f: Foo | EmptyFoo) {
if (f.kind === 1) {
(f: Foo);
}
}
"
`;
exports[`test test1.js 1`] = `
"// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
//////////////////////////////
// example with object types
//////////////////////////////
function obj(a: A1 | A2) {
return a.x;
}
const obj_result = obj({ x: \"\" }); // currently an error! (expect it to be OK)
// Type definitions used above are defined below, but in an order that
// deliberately makes their full resolution as lazy as possible. The call above
// blocks until A1 is partially resolved. Since the argument partially matches
// A1, that branch is selected. Later, that branch errors, but other branches
// have been lost by then.
type A1 = { x: B1 };
type A2 = { x: B2 };
type B1 = number;
type B2 = string;
(obj_result: B1 | B2);
///////////////////////////////////////
// similar example with function types
///////////////////////////////////////
function fun(a: A3 | A4) {
return a();
}
const fun_result = fun(() => \"\");
type A3 = () => B3;
type A4 = () => B4;
type B3 = number;
type B4 = string;
(fun_result: B3 | B4);
/////////////////////////////////////////////
// similar example with class instance types
/////////////////////////////////////////////
function inst(a: A5 | A6) { }
class B5 { }
class B6 { }
inst([new B6]);
type A5 = B5[];
type A6 = B6[];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
//////////////////////////////
// example with object types
//////////////////////////////
// currently an error! (expect it to be OK)
// Type definitions used above are defined below, but in an order that
// deliberately makes their full resolution as lazy as possible. The call above
// blocks until A1 is partially resolved. Since the argument partially matches
// A1, that branch is selected. Later, that branch errors, but other branches
// have been lost by then.
///////////////////////////////////////
// similar example with function types
///////////////////////////////////////
/////////////////////////////////////////////
// similar example with class instance types
/////////////////////////////////////////////
function obj(a: A1 | A2) {
return a.x;
}
const obj_result = obj({ x: \"\" });
type A1 = { x: B1 };
type A2 = { x: B2 };
type B1 = number;
type B2 = string;
(obj_result: B1 | B2);
function fun(a: A3 | A4) {
return a();
}
const fun_result = fun(() => \"\");
type A3 = () => B3;
type A4 = () => B4;
type B3 = number;
type B4 = string;
(fun_result: B3 | B4);
function inst(a: A5 | A6) {}
class B5 {}
class B6 {}
inst([ new B6() ]);
type A5 = B5[];
type A6 = B6[];
"
`;
exports[`test test2.js 1`] = `
"// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
//////////////////////////////
// example with object types
//////////////////////////////
function obj(a: { x: number } | { x: string }) { }
obj(({ x: \"\" }: A1));
type A1 = { x: B1 };
type B1 = string;
///////////////////////////////////////
// similar example with function types
///////////////////////////////////////
function fun(a: (() => number) | (() => string)) { }
fun(((() => \"\"): A2));
type A2 = () => B2;
type B2 = string;
/////////////////////////////////////////////////////
// similar example with generic class instance types
/////////////////////////////////////////////////////
class C<X> { }
function inst(a: C<number> | C<string>) { }
inst((new C: A3));
type A3 = C<B3>;
type B3 = string;
/////////////////////////////////////////////
// similar example with generic type aliases
/////////////////////////////////////////////
function alias(a: T<number> | T<string>) { }
alias({ x: (x: V<B4>) => { } });
type T<X> = { x: U<X> }
type U<X> = (x: V<X>) => void;
type V<X> = X;
type B4 = string;
// class statics
function stat(a: { x: number } | { x: string }) { }
class D {
static x: B5;
}
stat(D);
type B5 = string;
// tuples
function tup(a: [number,boolean] | [string,boolean]) { }
tup(([\"\",false]: A6));
type A6 = [B6,boolean];
type B6 = string;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
//////////////////////////////
// example with object types
//////////////////////////////
///////////////////////////////////////
// similar example with function types
///////////////////////////////////////
/////////////////////////////////////////////////////
// similar example with generic class instance types
/////////////////////////////////////////////////////
/////////////////////////////////////////////
// similar example with generic type aliases
/////////////////////////////////////////////
// class statics
// tuples
function obj(a: { x: number } | { x: string }) {}
obj(({ x: \"\" }: A1));
type A1 = { x: B1 };
type B1 = string;
function fun(a: (() => number) | (() => string)) {}
fun((() => \"\": A2));
type A2 = () => B2;
type B2 = string;
class C<X> {}
function inst(a: C<number> | C<string>) {}
inst((new C(): A3));
type A3 = C<B3>;
type B3 = string;
function alias(a: T<number> | T<string>) {}
alias({ x: (x: V<B4>) => {} });
type T<X> = { x: U<X> };
type U<X> = (x: V<X>) => void;
type V<X> = X;
type B4 = string;
function stat(a: { x: number } | { x: string }) {}
class D {
static x: B5;
}
stat(D);
type B5 = string;
function tup(a: [number, boolean] | [string, boolean]) {}
tup(([ \"\", false ]: A6));
type A6 = [B6, boolean];
type B6 = string;
"
`;
exports[`test test3.js 1`] = `
"// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
///////////////////////////////
// example with function types
///////////////////////////////
function fun(a: ((x: number) => void) | ((x: string) => void)) { }
fun((((x) => {}): A1));
type A1 = (x: B1) => void;
type B1 = string;
////////////////////////////
// example with array types
////////////////////////////
function arr(a: number[] | string[]) { }
arr(([]: A2));
type A2 = B2[];
type B2 = string;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
///////////////////////////////
// example with function types
///////////////////////////////
////////////////////////////
// example with array types
////////////////////////////
function fun(a: ((x: number) => void) | ((x: string) => void)) {}
fun((x => {}: A1));
type A1 = (x: B1) => void;
type B1 = string;
function arr(a: number[] | string[]) {}
arr(([]: A2));
type A2 = B2[];
type B2 = string;
"
`;
exports[`test test4.js 1`] = `
"// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
///////////////////////////////
// example with function types
///////////////////////////////
function fun(a: ((x: number) => void) | ((x: string) => void)) { }
const a1 = ((x) => {}: A1);
fun(a1);
function fun_call(x: string) { a1(x); }
type A1 = (x: B1) => void;
type B1 = string;
////////////////////////////
// example with array types
////////////////////////////
function arr(a: number[] | string[]) { }
const a2 = ([]: A2);
arr(a2);
function arr_set(x: string, i: number) { a2[i] = x; }
function arr_get(i: number): string { return a2[i]; }
type A2 = B2[];
type B2 = string;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
///////////////////////////////
// example with function types
///////////////////////////////
////////////////////////////
// example with array types
////////////////////////////
function fun(a: ((x: number) => void) | ((x: string) => void)) {}
const a1 = (x => {}: A1);
fun(a1);
function fun_call(x: string) {
a1(x);
}
type A1 = (x: B1) => void;
type B1 = string;
function arr(a: number[] | string[]) {}
const a2 = ([]: A2);
arr(a2);
function arr_set(x: string, i: number) {
a2[i] = x;
}
function arr_get(i: number): string {
return a2[i];
}
type A2 = B2[];
type B2 = string;
"
`;
exports[`test test5.js 1`] = `
"// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
///////////////////////////////
// example with function types
///////////////////////////////
function fun(a: ((x: number) => number) | ((x: string) => string)) { }
function a1(x) { return x; }
fun(a1);
function fun_call(x: string): string { return a1(x); }
/////////////////////////////
// example with array types
/////////////////////////////
function arr(a: number[] | string[]) { }
var a2 = [];
arr(a2);
function arr_set(x: string, i: number) { a2[i] = x; }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
///////////////////////////////
// example with function types
///////////////////////////////
/////////////////////////////
// example with array types
/////////////////////////////
function fun(a: ((x: number) => number) | ((x: string) => string)) {}
function a1(x) {
return x;
}
fun(a1);
function fun_call(x: string): string {
return a1(x);
}
function arr(a: number[] | string[]) {}
var a2 = [];
arr(a2);
function arr_set(x: string, i: number) {
a2[i] = x;
}
"
`;
exports[`test test6.js 1`] = `
"// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
//////////////////////////////////////////
// example with generic class inheritance
//////////////////////////////////////////
function inst(a: E<B4>): C<number> | C<string> { return a; }
const mk_C = () => C;
const mk_D = () => D;
const mk_E = () => E;
type B4 = string;
const _D = mk_D();
class E<X> extends _D<X> { }
const _C = mk_C();
class D<X> extends _C<X> { }
class C<X> { }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
//////////////////////////////////////////
// example with generic class inheritance
//////////////////////////////////////////
function inst(a: E<B4>): C<number> | C<string> {
return a;
}
const mk_C = () => C;
const mk_D = () => D;
const mk_E = () => E;
type B4 = string;
const _D = mk_D();
class E<X> extends _D<X> {}
const _C = mk_C();
class D<X> extends _C<X> {}
class C<X> {}
"
`;
exports[`test test7.js 1`] = `
"// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
////////////////////
// recursive types
////////////////////
function rec(x: F1 | F2) { }
rec({ x: 0 });
type F1 = G1;
type F2 = G2;
type G1 = { x: H1, y?: G1 };
type G2 = { x: H2, y?: G2 };
type H1 = string;
type H2 = number;
///////////////////////////////
// polymorphic recursive types
///////////////////////////////
function polyrec(x: PF<number> | PF<string>) { }
rec({ x: 0 });
type PF<X> = PG<X>;
type PG<X> = { x: X, y?: PG<X> };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
////////////////////
// recursive types
////////////////////
///////////////////////////////
// polymorphic recursive types
///////////////////////////////
function rec(x: F1 | F2) {}
rec({ x: 0 });
type F1 = G1;
type F2 = G2;
type G1 = { x: H1; y?: G1 };
type G2 = { x: H2; y?: G2 };
type H1 = string;
type H2 = number;
function polyrec(x: PF<number> | PF<string>) {}
rec({ x: 0 });
type PF<X> = PG<X>;
type PG<X> = { x: X; y?: PG<X> };
"
`;
exports[`test test8.js 1`] = `
"// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
//////////////////////
// nested union types
//////////////////////
function rec(x: F1 | F2) { }
rec({ x: 0 });
type F1 = G1 | G1_;
type F2 = G2 | G2_;
type G1 = { x: H1 };
type G1_ = { x: H1_ };
type G2 = { x: H2 };
type G2_ = { x: H2_ };
type H1 = boolean;
type H1_ = string;
type H2 = boolean;
type H2_ = number;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
//////////////////////
// nested union types
//////////////////////
function rec(x: F1 | F2) {}
rec({ x: 0 });
type F1 = G1 | G1_;
type F2 = G2 | G2_;
type G1 = { x: H1 };
type G1_ = { x: H1_ };
type G2 = { x: H2 };
type G2_ = { x: H2_ };
type H1 = boolean;
type H1_ = string;
type H2 = boolean;
type H2_ = number;
"
`;
exports[`test test9.js 1`] = `
"// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
////////////////
// interference
////////////////
function square(x? = 0) {
return x * x;
}
function foo(f: ((_: ?number) => ?number) | (() => void)) { }
foo((x): number => square(x))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
/**
* Test that shows how the implementation of union types is broken
*/
////////////////
// interference
////////////////
function square(x? = 0) {
return x * x;
}
function foo(f: ((_: ?number) => ?number) | (() => void)) {}
foo((x): number => square(x));
"
`;
exports[`test test10.js 1`] = `
"// @noflow
function id<X>(x: X): X { return x; }
/////////////////////////
// primitive annotations
/////////////////////////
function check_prim(_: number | string) { }
// ok
check_prim(\"\");
// ...even when they \"flow\" in
check_prim(id(\"\"));
//////////////////////////////
// class instance annotations
//////////////////////////////
class C { }
class D { }
function check_inst(_: C | D) { }
// ok
check_inst(new D);
// ...even when they \"flow\" in
check_inst(id(new C));
////////////////////////
// function annotations
////////////////////////
function check_fun(_: ((_: number) => number) | ((_: string) => string)) { }
// help!
check_fun((x) => x);
//////////////////////
// object annotations
//////////////////////
function check_obj(_: { x: number } | { x: string }) { }
// ok
check_obj({ x: \"\" });
// help!
check_obj({ x: id(\"\") });
/////////////////////
// array annotations
/////////////////////
function check_arr(_: number[] | string[]) { }
// ok
check_arr([\"\"]);
// help!
check_arr([id(\"\")]);
//////////////////////////////////////
// generic class instance annotations
//////////////////////////////////////
class P<X> { }
function check_poly_inst(_: P<number> | P<string>) { }
// help!
check_poly_inst(new P);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
/////////////////////////
// primitive annotations
/////////////////////////
// ok
// ...even when they \"flow\" in
//////////////////////////////
// class instance annotations
//////////////////////////////
// ok
// ...even when they \"flow\" in
////////////////////////
// function annotations
////////////////////////
// help!
//////////////////////
// object annotations
//////////////////////
// ok
// help!
/////////////////////
// array annotations
/////////////////////
// ok
// help!
//////////////////////////////////////
// generic class instance annotations
//////////////////////////////////////
// help!
function id<X>(x: X): X {
return x;
}
function check_prim(_: number | string) {}
check_prim(\"\");
check_prim(id(\"\"));
class C {}
class D {}
function check_inst(_: C | D) {}
check_inst(new D());
check_inst(id(new C()));
function check_fun(_: ((_: number) => number) | ((_: string) => string)) {}
check_fun(x => x);
function check_obj(_: { x: number } | { x: string }) {}
check_obj({ x: \"\" });
check_obj({ x: id(\"\") });
function check_arr(_: number[] | string[]) {}
check_arr([ \"\" ]);
check_arr([ id(\"\") ]);
class P<X> {}
function check_poly_inst(_: P<number> | P<string>) {}
check_poly_inst(new P());
"
`;
exports[`test test11.js 1`] = `
"// @noflow
// disjoint unions
function length(list: List) {
if (list.kind === \"cons\") return length(list.next) + 1;
else return 0;
}
length({ kind: \"nil\" });
length({ kind: \"cons\" }); // missing \`next\`
length({ kind: \"cons\", next: { kind: \"nil\" } });
length({ kind: \"empty\" }); // \`kind\` not found
type List = Nil | Cons;
type Nil = { kind: \"nil\" };
type Cons = { kind: \"cons\", next: List };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// disjoint unions
// missing \`next\`
// \`kind\` not found
function length(list: List) {
if (list.kind === \"cons\")
return length(list.next) + 1;
else
return 0;
}
length({ kind: \"nil\" });
length({ kind: \"cons\" });
length({ kind: \"cons\", next: { kind: \"nil\" } });
length({ kind: \"empty\" });
type List = Nil | Cons;
type Nil = { kind: \"nil\" };
type Cons = { kind: \"cons\"; next: List };
"
`;
exports[`test test12.js 1`] = `
"// @noflow
// polymorphic recursive types
type F<X> = { f: F<X>, x: X }
type G = { x: number }
type H = { x: string }
function rec(x: F<string>): G | H { return x; }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// polymorphic recursive types
type F<X> = { f: F<X>; x: X };
type G = { x: number };
type H = { x: string };
function rec(x: F<string>): G | H {
return x;
}
"
`;
exports[`test test13.js 1`] = `
"// @noflow
/* ensure there are no unintended side effects when trying branches */
({type: \'B\', id: \'hi\'}: {
type: \'A\';
id: ?string;
} | {
type: \'B\';
id: string;
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
/* ensure there are no unintended side effects when trying branches */
({ type: \"B\", id: \"hi\" }: { type: \"A\"; id: ?string } | {
type: \"B\";
id: string
});
"
`;
exports[`test test14.js 1`] = `
"// @noflow
// annotations
declare class C<X> {
get(): X;
}
function union(o: { x: string } | { x: number }) { }
function foo(c: C<number>) {
union({ x: c.get() });
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// annotations
declare class C<X> { get(): X }
function union(o: { x: string } | { x: number }) {}
function foo(c: C<number>) {
union({ x: c.get() });
}
"
`;
exports[`test test15.js 1`] = `
"// @noflow
// functions as objects
function foo<X>(target: EventTarget) {
target.addEventListener(\'click\', (e) => {});
}
declare class EventTarget {
addEventListener(type: \'foo\', listener: KeyboardEventHandler): void;
addEventListener(type: string, listener: EventHandler): void;
}
declare class Event { }
declare class KeyboardEvent { }
type EventHandler = (event: Event) => mixed
type KeyboardEventHandler = (event: KeyboardEvent) => mixed
// example where globals are not yet resolved
function bar(x: (() => void) | { x: number }) { }
bar(() => { });
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// functions as objects
// example where globals are not yet resolved
function foo<X>(target: EventTarget) {
target.addEventListener(\"click\", e => {});
}
declare class EventTarget {
addEventListener(type: \"foo\", listener: KeyboardEventHandler): void;
addEventListener(type: string, listener: EventHandler): void
}
declare class Event {}
declare class KeyboardEvent {}
type EventHandler = (event: Event) => mixed;
type KeyboardEventHandler = (event: KeyboardEvent) => mixed;
function bar(x: (() => void) | { x: number }) {}
bar(() => {});
"
`;
exports[`test test16.js 1`] = `
"// @noflow
// annotations
type T = number | (() => string);
type Foo = T | (() => bool);
type Bar = number | (() => string) | (() => bool);
function foo(x: Foo) { }
foo(() => qux());
function bar(x: Bar) { }
bar(() => qux());
var x = false;
function qux() { return x; }
x = \"\";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// annotations
type T = number | (() => string);
type Foo = T | (() => boolean);
type Bar = number | (() => string) | (() => boolean);
function foo(x: Foo) {}
foo(() => qux());
function bar(x: Bar) {}
bar(() => qux());
var x = false;
function qux() {
return x;
}
x = \"\";
"
`;
exports[`test test17.js 1`] = `
"// @noflow
// Array#concat
[].concat([]);
([].concat([0,1])[1]: string)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// Array#concat
[].concat([]);
([].concat([ 0, 1 ])[1]: string);
"
`;
exports[`test test18.js 1`] = `
"// @noflow
// method overloads
declare class C {
m(x: number): void;
m(x: string): void;
}
function f() { return 0; }
new C().m(f());
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// method overloads
declare class C { m(x: number): void; m(x: string): void }
function f() {
return 0;
}
new C().m(f());
"
`;
exports[`test test19.js 1`] = `
"// @noflow
// constructor overloads
function m<X>() {
return new D();
}
declare class D {
constructor(_: void): void;
constructor(_: null): void;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// constructor overloads
function m<X>() {
return new D();
}
declare class D { constructor(_: void): void; constructor(_: null): void }
"
`;
exports[`test test20.js 1`] = `
"// @noflow
// Array#reduce
[0,1].reduce((x,y,i) => y);
[\"a\", \"b\"].reduce(
(regex, representation, index) => {
return regex + (index ? \'|\' : \'\') + \'(\' + representation + \')\';
},
\'\',
);
[\"\"].reduce((acc,str) => acc * str.length);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// Array#reduce
[ 0, 1 ].reduce((x, y, i) => y);
[ \"a\", \"b\" ].reduce((regex, representation, index) => {
return regex + ((index ? \"|\" : \"\")) + \"(\" + representation + \")\";
}, \"\");
[ \"\" ].reduce((acc, str) => acc * str.length);
"
`;
exports[`test test21.js 1`] = `
"// @noflow
// annotations for disjoint unions
type T =
| { type: \"FOO\", x: number }
| { type: \"BAR\", x: string }
({ type: (bar(): \"BAR\"), x: str() }: T);
({ type: bar(), x: str() }: T);
({ type: bar(), x: (str(): string) }: T);
function bar() {
return \"BAR\";
}
function str() {
return \"hello\";
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// annotations for disjoint unions
type T = { type: \"FOO\"; x: number } | { type: \"BAR\"; x: string };
({ type: (bar(): \"BAR\"), x: str() }: T);
({ type: bar(), x: str() }: T);
({ type: bar(), x: (str(): string) }: T);
function bar() {
return \"BAR\";
}
function str() {
return \"hello\";
}
"
`;
exports[`test test22.js 1`] = `
"// @noflow
// refinement of disjoint unions
type Empty = { }
type Success = {
type: \'SUCCESS\';
result: string;
};
type Error = {
type: \'ERROR\';
} & Empty;
export type T = Success | Error;
function foo(x: T) {
if (x.type === \'SUCCESS\') return x.result;
else return x.result;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// refinement of disjoint unions
type Empty = {};
type Success = { type: \"SUCCESS\"; result: string };
type Error = { type: \"ERROR\" } & Empty;
export type T = Success | Error;
function foo(x: T) {
if (x.type === \"SUCCESS\")
return x.result;
else
return x.result;
}
"
`;
exports[`test test23.js 1`] = `
"// @noflow
// nested intersections (see also lib/test23_lib.js)
type NestedObj = { } & { dummy: SomeLibClass };
type Obj = NestedObj & { x: string };
function foo(obj: Obj) {
obj.x; // should be OK
obj.x; // should also be OK (the check above shouldn\'t affect anything)
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// nested intersections (see also lib/test23_lib.js)
// should be OK
// should also be OK (the check above shouldn\'t affect anything)
type NestedObj = {} & { dummy: SomeLibClass };
type Obj = NestedObj & { x: string };
function foo(obj: Obj) {
obj.x;
obj.x;
}
"
`;
exports[`test test24.js 1`] = `
"// @noflow
// scaling test for full type resolution
declare class C {
addListener(event: string, listener: Function): C;
emit(event: string, ...args:Array<any>): boolean;
listeners(event: string): Array<Function>;
listenerCount(event: string): number;
on(event: string, listener: Function): C;
once(event: string, listener: Function): C;
removeAllListeners(event?: string): C;
removeListener(event: string, listener: Function): C;
setMaxListeners(n: number): void;
}
declare class D extends C {
listen(port: number, hostname?: string, backlog?: number, callback?: Function): D;
listen(path: string, callback?: Function): D;
listen(handle: Object, callback?: Function): D;
close(callback?: Function): D;
address(): number;
connections: number;
maxConnections: number;
getConnections(callback: Function): void;
ref(): D;
unref(): D;
}
(0: D | number);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// scaling test for full type resolution
declare class C {
addListener(event: string, listener: Function): C;
emit(event: string, ...args: Array<any>): boolean;
listeners(event: string): Array<Function>;
listenerCount(event: string): number;
on(event: string, listener: Function): C;
once(event: string, listener: Function): C;
removeAllListeners(event?: string): C;
removeListener(event: string, listener: Function): C;
setMaxListeners(n: number): void
}
declare class D extends C {
listen(port: number,
hostname?: string,
backlog?: number,
callback?: Function): D;
listen(path: string, callback?: Function): D;
listen(handle: Object, callback?: Function): D;
close(callback?: Function): D;
address(): number;
connections: number;
maxConnections: number;
getConnections(callback: Function): void;
ref(): D;
unref(): D
}
(0: D | number);
"
`;
exports[`test test25.js 1`] = `
"// @noflow
// termination test (see also lib/test25_lib.js)
function foo(rows: Rows, set: Set<number>) {
return rows.reduce_rows(
(set, row) => row.reduce_row(
(set, i) => set.add(i),
set,
),
set,
);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// termination test (see also lib/test25_lib.js)
function foo(rows: Rows, set: Set<number>) {
return rows.reduce_rows(
(set, row) => row.reduce_row((set, i) => set.add(i), set),
set
);
}
"
`;
exports[`test test26.js 1`] = `
"// @noflow
declare function foo(x: number): number;
declare function foo(x: string): string;
declare var x: number | string;
(foo(x): number | string);
type T = number | string;
declare var y: T;
(foo(y): T);
declare class Record {
set(x: \'foo\', y: number): void;
set(x: \'bar\', y: string): void;
}
new Record().set(\'foo\', \"42\");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
declare function foo(x: number): number;
declare function foo(x: string): string;
declare var x: number | string;
(foo(x): number | string);
type T = number | string;
declare var y: T;
(foo(y): T);
declare class Record {
set(x: \"foo\", y: number): void;
set(x: \"bar\", y: string): void
}
new Record().set(\"foo\", \"42\");
"
`;
exports[`test test27.js 1`] = `
"// @noflow
type X = ({a:true} & {b:string}) | ({a:false} & {c:string});
//type X = {a:true, b:string} | {a:false, c:string}; // this works.
function hello1(x:X): string {
if (x.a === true) return x.b; else return x.c;
}
function hello2(x:X): string {
if (x.a === false) return x.c; else return x.b;
}
function hello3(x:X): string {
if (x.a) { return x.b; } else { return x.c; }
}
function hello4(x:X): string {
if (!x.a) { return x.c; } else { return x.b; }
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
//type X = {a:true, b:string} | {a:false, c:string}; // this works.
type X = ({ a: true } & { b: string }) | ({ a: false } & { c: string });
function hello1(x: X): string {
if (x.a === true)
return x.b;
else
return x.c;
}
function hello2(x: X): string {
if (x.a === false)
return x.c;
else
return x.b;
}
function hello3(x: X): string {
if (x.a) {
return x.b;
} else {
return x.c;
}
}
function hello4(x: X): string {
if (!x.a) {
return x.c;
} else {
return x.b;
}
}
"
`;
exports[`test test29.js 1`] = `
"// @noflow
// Make sure caching doesn\'t cause a spurious successful match (e.g., when a
// failed match is tried again). This may happen, e.g., when checking
// polymorphic definitions, where the same code may be checked multiple times
// with different instantiations.
type Row = { x: string };
declare class D<T> {
reduce(
callbackfn: (previousValue: T, currentValue: T) => T,
initialValue: void
): T;
reduce<U>(
callbackfn: (previousValue: U, currentValue: T) => U,
initialValue: U
): U;
}
class C {
foo(
rows: D<Row>,
minWidth: number,
): number {
return rows.reduce(
(length, row) => 0,
minWidth,
);
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// Make sure caching doesn\'t cause a spurious successful match (e.g., when a
// failed match is tried again). This may happen, e.g., when checking
// polymorphic definitions, where the same code may be checked multiple times
// with different instantiations.
type Row = { x: string };
declare class D<T> {
reduce(callbackfn: (previousValue: T, currentValue: T) => T,
initialValue: void): T;
reduce<U>(callbackfn: (previousValue: U, currentValue: T) => U,
initialValue: U): U
}
class C {
foo(rows: D<Row>, minWidth: number): number {
return rows.reduce((length, row) => 0, minWidth);
}
}
"
`;
exports[`test test30.js 1`] = `
"// @noflow
const Constants = require(\'./test30-helper\');
type ActionType =
| { type: \'foo\', x: number }
| { type: \'bar\', x: number }
({ type: Constants.BAR, x: 0 }: ActionType);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
const Constants = require(\"./test30-helper\");
type ActionType = { type: \"foo\"; x: number } | { type: \"bar\"; x: number };
({ type: Constants.BAR, x: 0 }: ActionType);
"
`;
exports[`test test30-helper.js 1`] = `
"// @noflow
module.exports = {
FOO: \'foo\',
BAR: \'bar\',
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
module.exports = { FOO: \"foo\", BAR: \"bar\" };
"
`;
exports[`test test31.js 1`] = `
"// @noflow
// make sure tuples are type arguments (as used e.g. when viewing maps as
// key/value iterables) work
interface SomeIterator<T> { }
interface SomeIterable<T> {
it(): SomeIterator<T>;
}
declare class SomeMap<K,V> {
it(): SomeIterator<[K,V]>;
set(k: K, v: V): void;
}
declare class ImmutableMap<K,V> { }
declare function convert<K,V>(iter: SomeIterable<[K,V]>): ImmutableMap<K,V>;
function foo(): ImmutableMap<string, boolean> {
const countersGlobalMap = new SomeMap();
countersGlobalMap.set(\"\", false);
return convert(countersGlobalMap);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
// make sure tuples are type arguments (as used e.g. when viewing maps as
// key/value iterables) work
interface SomeIterator<T> {}
interface SomeIterable<T> { it(): SomeIterator<T> }
declare class SomeMap<K, V> {
it(): SomeIterator<[K, V]>;
set(k: K, v: V): void
}
declare class ImmutableMap<K, V> {}
declare function convert<K, V>(iter: SomeIterable<[K, V]>): ImmutableMap<K, V>;
function foo(): ImmutableMap<string, boolean> {
const countersGlobalMap = new SomeMap();
countersGlobalMap.set(\"\", false);
return convert(countersGlobalMap);
}
"
`;
exports[`test test32.js 1`] = `
"// @flow
// make sure that full resolution jobs don\'t cache improperly to signal success
// when they have failed earlier
function foo(value: Indirect<string> | number): Indirect<string> | number {
const castedValue: number = typeof value === \'number\' ? value : 0;
return castedValue;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// make sure that full resolution jobs don\'t cache improperly to signal success
// when they have failed earlier
function foo(value: Indirect<string> | number): Indirect<string> | number {
const castedValue: number = (typeof value === \"number\" ? value : 0);
return castedValue;
}
"
`;