1929 lines
39 KiB
Plaintext
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;
|
|
}
|
|
"
|
|
`;
|