2099 lines
38 KiB
Plaintext
2099 lines
38 KiB
Plaintext
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
|
|
exports[`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[`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[`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[`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[`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[`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[`issue-1455-helper.js 1`] = `
|
|
/* @flow */
|
|
|
|
export class Foobar { }
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
/* @flow */
|
|
|
|
export class Foobar {}
|
|
|
|
`;
|
|
|
|
exports[`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
|
|
}
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
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
|
|
}
|
|
|
|
`;
|
|
|
|
exports[`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[`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[`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 });
|
|
//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;
|
|
}
|
|
|
|
`;
|
|
|
|
exports[`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 */
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
`;
|
|
|
|
exports[`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
|
|
//////////////////////////////
|
|
|
|
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[];
|
|
|
|
`;
|
|
|
|
exports[`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
|
|
//////////////////////////////
|
|
|
|
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;
|
|
|
|
`;
|
|
|
|
exports[`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
|
|
///////////////////////////////
|
|
|
|
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;
|
|
|
|
`;
|
|
|
|
exports[`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
|
|
///////////////////////////////
|
|
|
|
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;
|
|
|
|
`;
|
|
|
|
exports[`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
|
|
///////////////////////////////
|
|
|
|
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;
|
|
}
|
|
|
|
`;
|
|
|
|
exports[`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[`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
|
|
////////////////////
|
|
|
|
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> };
|
|
|
|
`;
|
|
|
|
exports[`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[`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[`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[]) { }
|
|
|
|
// help! (unlike objects, array literals' element types are always open)
|
|
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
|
|
|
|
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[]) {}
|
|
|
|
// help! (unlike objects, array literals' element types are always open)
|
|
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());
|
|
|
|
`;
|
|
|
|
exports[`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
|
|
|
|
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 };
|
|
|
|
`;
|
|
|
|
exports[`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[`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[`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[`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
|
|
|
|
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(() => {});
|
|
|
|
`;
|
|
|
|
exports[`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[`test17.js 1`] = `
|
|
// @noflow
|
|
|
|
// Array#concat
|
|
|
|
[].concat([]);
|
|
|
|
([].concat([0,1])[1]: string)
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// @noflow
|
|
|
|
// Array#concat
|
|
|
|
[].concat([]);
|
|
|
|
([].concat([0, 1])[1]: string);
|
|
|
|
`;
|
|
|
|
exports[`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[`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[`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[`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[`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[`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)
|
|
|
|
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)
|
|
}
|
|
|
|
`;
|
|
|
|
exports[`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[`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[`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[`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 });
|
|
//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;
|
|
}
|
|
}
|
|
|
|
`;
|
|
|
|
exports[`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[`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[`test30-helper.js 1`] = `
|
|
// @noflow
|
|
|
|
module.exports = {
|
|
FOO: 'foo',
|
|
BAR: 'bar',
|
|
}
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// @noflow
|
|
|
|
module.exports = {
|
|
FOO: "foo",
|
|
BAR: "bar"
|
|
};
|
|
|
|
`;
|
|
|
|
exports[`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[`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;
|
|
}
|
|
|
|
`;
|