2016-12-23 22:31:38 +03:00
|
|
|
exports[`test all.js 1`] = `
|
|
|
|
"// @flow
|
|
|
|
|
|
|
|
declare var pstr: Promise<string>;
|
|
|
|
declare var pnum: Promise<number>;
|
|
|
|
|
|
|
|
Promise.all([
|
|
|
|
pstr,
|
|
|
|
pnum,
|
|
|
|
true, // non-Promise values passed through
|
|
|
|
]).then((xs) => {
|
|
|
|
// tuple information is preserved
|
|
|
|
let [a,b,c] = xs;
|
|
|
|
(a: number); // Error: string ~> number
|
|
|
|
(b: boolean); // Error: number ~> boolean
|
|
|
|
(c: string); // Error: boolean ~> string
|
|
|
|
|
|
|
|
// array element type is (string | number | boolean)
|
|
|
|
xs.forEach(x => {
|
|
|
|
(x: void); // Errors: string ~> void, number ~> void, boolean ~> void
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
// First argument is required
|
|
|
|
Promise.all(); // Error: expected array instead of undefined (too few arguments)
|
|
|
|
|
|
|
|
// Mis-typed arg
|
|
|
|
Promise.all(0); // Error: expected array instead of number
|
|
|
|
|
|
|
|
// Promise.all is a function
|
|
|
|
(Promise.all : Function);
|
|
|
|
|
|
|
|
// Promise.all supports iterables
|
|
|
|
function test(val: Iterable<Promise<number>>) {
|
|
|
|
const r: Promise<Array<number>> = Promise.all(val);
|
|
|
|
}
|
|
|
|
|
|
|
|
function tes2(val: Map<string, Promise<number>>) {
|
|
|
|
const r: Promise<Array<number>> = Promise.all(val.values());
|
|
|
|
}
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2016-12-27 21:29:31 +03:00
|
|
|
// @flow
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2016-12-27 21:29:31 +03:00
|
|
|
declare var pstr: Promise<string>;
|
|
|
|
declare var pnum: Promise<number>;
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
Promise.all([
|
|
|
|
pstr,
|
|
|
|
pnum,
|
2017-01-26 22:57:43 +03:00
|
|
|
true // non-Promise values passed through
|
2017-01-10 05:49:06 +03:00
|
|
|
]).then(xs => {
|
|
|
|
// tuple information is preserved
|
2017-01-24 22:38:12 +03:00
|
|
|
let [a, b, c] = xs;
|
2017-01-26 22:57:43 +03:00
|
|
|
(a: number); // Error: string ~> number
|
|
|
|
(b: boolean); // Error: number ~> boolean
|
|
|
|
(c: string); // Error: boolean ~> string
|
2017-01-10 05:49:06 +03:00
|
|
|
// array element type is (string | number | boolean)
|
2017-01-04 23:24:10 +03:00
|
|
|
xs.forEach(x => {
|
2017-01-10 05:49:06 +03:00
|
|
|
(x: void); // Errors: string ~> void, number ~> void, boolean ~> void
|
2017-01-04 23:24:10 +03:00
|
|
|
});
|
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// First argument is required
|
2017-01-26 22:57:43 +03:00
|
|
|
Promise.all(); // Error: expected array instead of undefined (too few arguments)
|
2017-01-10 05:49:06 +03:00
|
|
|
// Mis-typed arg
|
2017-01-26 22:57:43 +03:00
|
|
|
Promise.all(0); // Error: expected array instead of number
|
2017-01-10 05:49:06 +03:00
|
|
|
// Promise.all is a function
|
2016-12-27 21:29:31 +03:00
|
|
|
(Promise.all: Function);
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// Promise.all supports iterables
|
2016-12-27 21:29:31 +03:00
|
|
|
function test(val: Iterable<Promise<number>>) {
|
|
|
|
const r: Promise<Array<number>> = Promise.all(val);
|
|
|
|
}
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2016-12-27 21:29:31 +03:00
|
|
|
function tes2(val: Map<string, Promise<number>>) {
|
|
|
|
const r: Promise<Array<number>> = Promise.all(val.values());
|
2017-01-11 18:16:38 +03:00
|
|
|
}
|
|
|
|
"
|
2016-12-23 22:31:38 +03:00
|
|
|
`;
|
|
|
|
|
|
|
|
exports[`test covariance.js 1`] = `
|
|
|
|
"/* @flow */
|
|
|
|
|
|
|
|
async function testAll() {
|
|
|
|
/* This is a test case from https://github.com/facebook/flow/issues/1143
|
2016-12-30 19:56:42 +03:00
|
|
|
* which was previously an error due to Array\'s invariance and an improper
|
2016-12-23 22:31:38 +03:00
|
|
|
* definition of Promise.all */
|
|
|
|
const x: Array<Promise<?string>> = [];
|
|
|
|
const y: Promise<Array<?string>> = Promise.all(x);
|
|
|
|
const z: Array<?string> = await y;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function testRace() {
|
|
|
|
const x: Array<Promise<?string>> = [];
|
|
|
|
const y: Promise<?string> = Promise.race(x);
|
|
|
|
const z: ?string = await y;
|
|
|
|
}
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2016-12-27 21:29:31 +03:00
|
|
|
/* @flow */
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
async function testAll() {
|
|
|
|
/* This is a test case from https://github.com/facebook/flow/issues/1143
|
2016-12-30 19:56:42 +03:00
|
|
|
* which was previously an error due to Array\'s invariance and an improper
|
2016-12-27 21:29:31 +03:00
|
|
|
* definition of Promise.all */
|
2016-12-31 07:01:07 +03:00
|
|
|
const x: Array<Promise<?string>> = [];
|
2016-12-27 21:29:31 +03:00
|
|
|
const y: Promise<Array<?string>> = Promise.all(x);
|
|
|
|
const z: Array<?string> = await y;
|
|
|
|
}
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2016-12-27 21:29:31 +03:00
|
|
|
async function testRace() {
|
2016-12-31 07:01:07 +03:00
|
|
|
const x: Array<Promise<?string>> = [];
|
2016-12-27 21:29:31 +03:00
|
|
|
const y: Promise<?string> = Promise.race(x);
|
|
|
|
const z: ?string = await y;
|
2017-01-11 18:16:38 +03:00
|
|
|
}
|
|
|
|
"
|
2016-12-23 22:31:38 +03:00
|
|
|
`;
|
|
|
|
|
|
|
|
exports[`test promise.js 1`] = `
|
|
|
|
"/**
|
|
|
|
* @flow
|
|
|
|
*/
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
// == Promise constructor resolve() function == //
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// Promise constructor resolve(T) -> then(T)
|
|
|
|
new Promise(function(resolve, reject) {
|
|
|
|
resolve(0);
|
|
|
|
}).then(function(num) {
|
|
|
|
var a: number = num;
|
|
|
|
|
|
|
|
// TODO: The error message that results from this is almost useless
|
|
|
|
var b: string = num; // Error: number ~> string
|
|
|
|
});
|
|
|
|
|
|
|
|
// Promise constructor with arrow function resolve(T) -> then(T)
|
|
|
|
new Promise((resolve, reject) => resolve(0))
|
|
|
|
.then(function(num) {
|
|
|
|
var a: number = num;
|
|
|
|
|
|
|
|
// TODO: The error message that results from this is almost useless
|
|
|
|
var b: string = num; // Error: number ~> string
|
|
|
|
});
|
|
|
|
|
|
|
|
// Promise constructor resolve(Promise<T>) -> then(T)
|
|
|
|
new Promise(function(resolve, reject) {
|
|
|
|
resolve(new Promise(function(resolve, reject) {
|
|
|
|
resolve(0);
|
|
|
|
}));
|
|
|
|
}).then(function(num) {
|
|
|
|
var a: number = num;
|
|
|
|
var b: string = num; // Error: number ~> string
|
|
|
|
});
|
|
|
|
|
|
|
|
// Promise constructor resolve(Promise<Promise<T>>) -> then(T)
|
|
|
|
new Promise(function(resolve, reject) {
|
|
|
|
resolve(new Promise(function(resolve, reject) {
|
|
|
|
resolve(new Promise(function(resolve, reject) {
|
|
|
|
resolve(0);
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
}).then(function(num) {
|
|
|
|
var a: number = num;
|
|
|
|
var b: string = num; // Error: number ~> string
|
|
|
|
});
|
|
|
|
|
|
|
|
// Promise constructor resolve(T); resolve(U); -> then(T|U)
|
|
|
|
new Promise(function(resolve, reject) {
|
|
|
|
if (Math.random()) {
|
|
|
|
resolve(42);
|
|
|
|
} else {
|
2016-12-30 19:56:42 +03:00
|
|
|
resolve(\'str\');
|
2016-12-23 22:31:38 +03:00
|
|
|
}
|
|
|
|
}).then(function(numOrStr) {
|
2016-12-30 19:56:42 +03:00
|
|
|
if (typeof numOrStr === \'string\') {
|
2016-12-23 22:31:38 +03:00
|
|
|
var a: string = numOrStr;
|
|
|
|
} else {
|
|
|
|
var b: number = numOrStr;
|
|
|
|
}
|
|
|
|
var c: string = numOrStr; // Error: number|string -> string
|
|
|
|
});
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////
|
|
|
|
// == Promise constructor reject() function == //
|
|
|
|
/////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// TODO: Promise constructor reject(T) -> catch(T)
|
|
|
|
new Promise(function(resolve, reject) {
|
|
|
|
reject(0);
|
|
|
|
}).catch(function(num) {
|
|
|
|
var a: number = num;
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
var b: string = num; // Error: number ~> string
|
|
|
|
});
|
|
|
|
|
|
|
|
// TODO: Promise constructor reject(Promise<T>) ~> catch(Promise<T>)
|
|
|
|
new Promise(function(resolve, reject) {
|
|
|
|
reject(new Promise(function(resolve, reject) {
|
|
|
|
reject(0);
|
|
|
|
}));
|
|
|
|
}).catch(function(num) {
|
|
|
|
var a: Promise<number> = num;
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
var b: number = num; // Error: Promise<Number> ~> number
|
|
|
|
});
|
|
|
|
|
|
|
|
// TODO: Promise constructor reject(T); reject(U); -> then(T|U)
|
|
|
|
new Promise(function(resolve, reject) {
|
|
|
|
if (Math.random()) {
|
|
|
|
reject(42);
|
|
|
|
} else {
|
2016-12-30 19:56:42 +03:00
|
|
|
reject(\'str\');
|
2016-12-23 22:31:38 +03:00
|
|
|
}
|
|
|
|
}).catch(function(numOrStr) {
|
2016-12-30 19:56:42 +03:00
|
|
|
if (typeof numOrStr === \'string\') {
|
2016-12-23 22:31:38 +03:00
|
|
|
var a: string = numOrStr;
|
|
|
|
} else {
|
|
|
|
var b: number = numOrStr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
var c: string = numOrStr; // Error: number|string -> string
|
|
|
|
});
|
|
|
|
|
|
|
|
/////////////////////////////
|
|
|
|
// == Promise.resolve() == //
|
|
|
|
/////////////////////////////
|
|
|
|
|
|
|
|
// Promise.resolve(T) -> then(T)
|
|
|
|
Promise.resolve(0).then(function(num) {
|
|
|
|
var a: number = num;
|
|
|
|
var b: string = num; // Error: number ~> string
|
|
|
|
});
|
|
|
|
|
|
|
|
// Promise.resolve(Promise<T>) -> then(T)
|
|
|
|
Promise.resolve(Promise.resolve(0)).then(function(num) {
|
|
|
|
var a: number = num;
|
|
|
|
var b: string = num; // Error: number ~> string
|
|
|
|
});
|
|
|
|
|
|
|
|
// Promise.resolve(Promise<Promise<T>>) -> then(T)
|
|
|
|
Promise.resolve(Promise.resolve(Promise.resolve(0))).then(function(num) {
|
|
|
|
var a: number = num;
|
|
|
|
var b: string = num; // Error: number ~> string
|
|
|
|
});
|
|
|
|
|
|
|
|
////////////////////////////
|
|
|
|
// == Promise.reject() == //
|
|
|
|
////////////////////////////
|
|
|
|
|
|
|
|
// TODO: Promise.reject(T) -> catch(T)
|
|
|
|
Promise.reject(0).catch(function(num) {
|
|
|
|
var a: number = num;
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
var b: string = num; // Error: number ~> string
|
|
|
|
});
|
|
|
|
|
|
|
|
// TODO: Promise.reject(Promise<T>) -> catch(Promise<T>)
|
|
|
|
Promise.reject(Promise.resolve(0)).then(function(num) {
|
|
|
|
var a: Promise<number> = num;
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
var b: number = num; // Error: Promise<number> ~> number
|
|
|
|
});
|
|
|
|
|
|
|
|
//////////////////////////////////
|
|
|
|
// == Promise.prototype.then == //
|
|
|
|
//////////////////////////////////
|
|
|
|
|
|
|
|
// resolvedPromise.then():T -> then(T)
|
|
|
|
Promise.resolve(0)
|
2016-12-30 19:56:42 +03:00
|
|
|
.then(function(num) { return \'asdf\'; })
|
2016-12-23 22:31:38 +03:00
|
|
|
.then(function(str) {
|
|
|
|
var a: string = str;
|
|
|
|
var b: number = str; // Error: string ~> number
|
|
|
|
});
|
|
|
|
|
|
|
|
// resolvedPromise.then():Promise<T> -> then(T)
|
|
|
|
Promise.resolve(0)
|
2016-12-30 19:56:42 +03:00
|
|
|
.then(function(num) { return Promise.resolve(\'asdf\'); })
|
2016-12-23 22:31:38 +03:00
|
|
|
.then(function(str) {
|
|
|
|
var a: string = str;
|
|
|
|
var b: number = str; // Error: string ~> number
|
|
|
|
});
|
|
|
|
|
|
|
|
// resolvedPromise.then():Promise<Promise<T>> -> then(T)
|
|
|
|
Promise.resolve(0)
|
2016-12-30 19:56:42 +03:00
|
|
|
.then(function(num) { return Promise.resolve(Promise.resolve(\'asdf\')); })
|
2016-12-23 22:31:38 +03:00
|
|
|
.then(function(str) {
|
|
|
|
var a: string = str;
|
|
|
|
var b: number = str; // Error: string ~> number
|
|
|
|
});
|
|
|
|
|
|
|
|
// TODO: resolvedPromise.then(<throw(T)>) -> catch(T)
|
|
|
|
Promise.resolve(0)
|
|
|
|
.then(function(num) {
|
2016-12-30 19:56:42 +03:00
|
|
|
throw \'str\';
|
2016-12-23 22:31:38 +03:00
|
|
|
})
|
|
|
|
.catch(function(str) {
|
|
|
|
var a: string = str;
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
var b: number = str; // Error: string ~> number
|
|
|
|
});
|
|
|
|
|
|
|
|
///////////////////////////////////
|
|
|
|
// == Promise.prototype.catch == //
|
|
|
|
///////////////////////////////////
|
|
|
|
|
|
|
|
// rejectedPromise.catch():U -> then(U)
|
|
|
|
Promise.reject(0)
|
2016-12-30 19:56:42 +03:00
|
|
|
.catch(function(num) { return \'asdf\'; })
|
2016-12-23 22:31:38 +03:00
|
|
|
.then(function(str) {
|
|
|
|
var a: string = str;
|
|
|
|
var b: number = str; // Error: string ~> number
|
|
|
|
});
|
|
|
|
|
|
|
|
// rejectedPromise.catch():Promise<U> -> then(U)
|
|
|
|
Promise.reject(0)
|
2016-12-30 19:56:42 +03:00
|
|
|
.catch(function(num) { return Promise.resolve(\'asdf\'); })
|
2016-12-23 22:31:38 +03:00
|
|
|
.then(function(str) {
|
|
|
|
var a: string = str;
|
|
|
|
var b: number = str; // Error: string ~> number
|
|
|
|
});
|
|
|
|
|
|
|
|
// rejectedPromise.catch():Promise<Promise<U>> -> then(U)
|
|
|
|
Promise.reject(0)
|
2016-12-30 19:56:42 +03:00
|
|
|
.catch(function(num) { return Promise.resolve(Promise.resolve(\'asdf\')); })
|
2016-12-23 22:31:38 +03:00
|
|
|
.then(function(str) {
|
|
|
|
var a: string = str;
|
|
|
|
var b: number = str; // Error: string ~> number
|
|
|
|
});
|
|
|
|
|
|
|
|
// TODO: resolvedPromise<T> -> catch() -> then():T
|
|
|
|
Promise.resolve(0)
|
|
|
|
.catch(function(err) {})
|
|
|
|
.then(function(num) {
|
|
|
|
var a: number = num;
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
var b: string = num; // Error: string ~> number
|
|
|
|
});
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2016-12-27 21:29:31 +03:00
|
|
|
/**
|
|
|
|
* @flow
|
|
|
|
*/
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2016-12-27 21:29:31 +03:00
|
|
|
//////////////////////////////////////////////////
|
|
|
|
// == Promise constructor resolve() function == //
|
|
|
|
//////////////////////////////////////////////////
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2016-12-27 21:29:31 +03:00
|
|
|
// Promise constructor resolve(T) -> then(T)
|
2017-01-04 23:24:10 +03:00
|
|
|
new Promise(function(resolve, reject) {
|
|
|
|
resolve(0);
|
|
|
|
}).then(function(num) {
|
|
|
|
var a: number = num;
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// TODO: The error message that results from this is almost useless
|
|
|
|
var b: string = num; // Error: number ~> string
|
2017-01-04 23:24:10 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// Promise constructor with arrow function resolve(T) -> then(T)
|
2017-01-04 23:24:10 +03:00
|
|
|
new Promise((resolve, reject) => resolve(0)).then(function(num) {
|
|
|
|
var a: number = num;
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// TODO: The error message that results from this is almost useless
|
|
|
|
var b: string = num; // Error: number ~> string
|
2017-01-04 23:24:10 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// Promise constructor resolve(Promise<T>) -> then(T)
|
2017-01-04 23:24:10 +03:00
|
|
|
new Promise(function(resolve, reject) {
|
|
|
|
resolve(new Promise(function(resolve, reject) {
|
2017-01-05 06:26:46 +03:00
|
|
|
resolve(0);
|
|
|
|
}));
|
2017-01-04 23:24:10 +03:00
|
|
|
}).then(function(num) {
|
|
|
|
var a: number = num;
|
2017-01-10 05:49:06 +03:00
|
|
|
var b: string = num; // Error: number ~> string
|
2017-01-04 23:24:10 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// Promise constructor resolve(Promise<Promise<T>>) -> then(T)
|
2017-01-04 23:24:10 +03:00
|
|
|
new Promise(function(resolve, reject) {
|
|
|
|
resolve(new Promise(function(resolve, reject) {
|
2017-01-05 06:26:46 +03:00
|
|
|
resolve(new Promise(function(resolve, reject) {
|
|
|
|
resolve(0);
|
2017-01-04 23:24:10 +03:00
|
|
|
}));
|
2017-01-05 06:26:46 +03:00
|
|
|
}));
|
2017-01-04 23:24:10 +03:00
|
|
|
}).then(function(num) {
|
|
|
|
var a: number = num;
|
2017-01-10 05:49:06 +03:00
|
|
|
var b: string = num; // Error: number ~> string
|
2017-01-04 23:24:10 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// Promise constructor resolve(T); resolve(U); -> then(T|U)
|
2017-01-04 23:24:10 +03:00
|
|
|
new Promise(function(resolve, reject) {
|
|
|
|
if (Math.random()) {
|
|
|
|
resolve(42);
|
|
|
|
} else {
|
|
|
|
resolve(\"str\");
|
2016-12-27 21:29:31 +03:00
|
|
|
}
|
2017-01-04 23:24:10 +03:00
|
|
|
}).then(function(numOrStr) {
|
|
|
|
if (typeof numOrStr === \"string\") {
|
|
|
|
var a: string = numOrStr;
|
|
|
|
} else {
|
|
|
|
var b: number = numOrStr;
|
2016-12-27 21:29:31 +03:00
|
|
|
}
|
2017-01-10 05:49:06 +03:00
|
|
|
var c: string = numOrStr; // Error: number|string -> string
|
2017-01-04 23:24:10 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
/////////////////////////////////////////////////
|
|
|
|
// == Promise constructor reject() function == //
|
|
|
|
/////////////////////////////////////////////////
|
2017-01-27 22:05:41 +03:00
|
|
|
|
2017-01-10 05:49:06 +03:00
|
|
|
// TODO: Promise constructor reject(T) -> catch(T)
|
2017-01-04 23:24:10 +03:00
|
|
|
new Promise(function(resolve, reject) {
|
|
|
|
reject(0);
|
|
|
|
}).catch(function(num) {
|
|
|
|
var a: number = num;
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// TODO
|
|
|
|
var b: string = num; // Error: number ~> string
|
2017-01-04 23:24:10 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// TODO: Promise constructor reject(Promise<T>) ~> catch(Promise<T>)
|
2017-01-04 23:24:10 +03:00
|
|
|
new Promise(function(resolve, reject) {
|
|
|
|
reject(new Promise(function(resolve, reject) {
|
2017-01-05 06:26:46 +03:00
|
|
|
reject(0);
|
|
|
|
}));
|
2017-01-04 23:24:10 +03:00
|
|
|
}).catch(function(num) {
|
|
|
|
var a: Promise<number> = num;
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// TODO
|
|
|
|
var b: number = num; // Error: Promise<Number> ~> number
|
2017-01-04 23:24:10 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// TODO: Promise constructor reject(T); reject(U); -> then(T|U)
|
2017-01-04 23:24:10 +03:00
|
|
|
new Promise(function(resolve, reject) {
|
|
|
|
if (Math.random()) {
|
|
|
|
reject(42);
|
|
|
|
} else {
|
|
|
|
reject(\"str\");
|
2016-12-27 21:29:31 +03:00
|
|
|
}
|
2017-01-04 23:24:10 +03:00
|
|
|
}).catch(function(numOrStr) {
|
|
|
|
if (typeof numOrStr === \"string\") {
|
|
|
|
var a: string = numOrStr;
|
|
|
|
} else {
|
|
|
|
var b: number = numOrStr;
|
2016-12-27 21:29:31 +03:00
|
|
|
}
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// TODO
|
|
|
|
var c: string = numOrStr; // Error: number|string -> string
|
2017-01-04 23:24:10 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
/////////////////////////////
|
|
|
|
// == Promise.resolve() == //
|
|
|
|
/////////////////////////////
|
2017-01-27 22:05:41 +03:00
|
|
|
|
2017-01-10 05:49:06 +03:00
|
|
|
// Promise.resolve(T) -> then(T)
|
2017-01-04 23:24:10 +03:00
|
|
|
Promise.resolve(0).then(function(num) {
|
|
|
|
var a: number = num;
|
2017-01-10 05:49:06 +03:00
|
|
|
var b: string = num; // Error: number ~> string
|
2017-01-04 23:24:10 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// Promise.resolve(Promise<T>) -> then(T)
|
2017-01-04 23:24:10 +03:00
|
|
|
Promise.resolve(Promise.resolve(0)).then(function(num) {
|
|
|
|
var a: number = num;
|
2017-01-10 05:49:06 +03:00
|
|
|
var b: string = num; // Error: number ~> string
|
2017-01-04 23:24:10 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// Promise.resolve(Promise<Promise<T>>) -> then(T)
|
2017-01-04 23:24:10 +03:00
|
|
|
Promise.resolve(Promise.resolve(Promise.resolve(0))).then(function(num) {
|
|
|
|
var a: number = num;
|
2017-01-10 05:49:06 +03:00
|
|
|
var b: string = num; // Error: number ~> string
|
2017-01-04 23:24:10 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
////////////////////////////
|
|
|
|
// == Promise.reject() == //
|
|
|
|
////////////////////////////
|
2017-01-27 22:05:41 +03:00
|
|
|
|
2017-01-10 05:49:06 +03:00
|
|
|
// TODO: Promise.reject(T) -> catch(T)
|
2017-01-04 23:24:10 +03:00
|
|
|
Promise.reject(0).catch(function(num) {
|
|
|
|
var a: number = num;
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// TODO
|
|
|
|
var b: string = num; // Error: number ~> string
|
2017-01-04 23:24:10 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// TODO: Promise.reject(Promise<T>) -> catch(Promise<T>)
|
2017-01-04 23:24:10 +03:00
|
|
|
Promise.reject(Promise.resolve(0)).then(function(num) {
|
|
|
|
var a: Promise<number> = num;
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// TODO
|
|
|
|
var b: number = num; // Error: Promise<number> ~> number
|
2017-01-04 23:24:10 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
//////////////////////////////////
|
|
|
|
// == Promise.prototype.then == //
|
|
|
|
//////////////////////////////////
|
2017-01-27 22:05:41 +03:00
|
|
|
|
2017-01-10 05:49:06 +03:00
|
|
|
// resolvedPromise.then():T -> then(T)
|
2017-01-05 23:26:45 +03:00
|
|
|
Promise
|
|
|
|
.resolve(0)
|
|
|
|
.then(function(num) {
|
|
|
|
return \"asdf\";
|
|
|
|
})
|
|
|
|
.then(function(str) {
|
|
|
|
var a: string = str;
|
2017-01-10 05:49:06 +03:00
|
|
|
var b: number = str; // Error: string ~> number
|
2017-01-05 23:26:45 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// resolvedPromise.then():Promise<T> -> then(T)
|
2017-01-05 23:26:45 +03:00
|
|
|
Promise
|
|
|
|
.resolve(0)
|
|
|
|
.then(function(num) {
|
|
|
|
return Promise.resolve(\"asdf\");
|
|
|
|
})
|
|
|
|
.then(function(str) {
|
|
|
|
var a: string = str;
|
2017-01-10 05:49:06 +03:00
|
|
|
var b: number = str; // Error: string ~> number
|
2017-01-05 23:26:45 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// resolvedPromise.then():Promise<Promise<T>> -> then(T)
|
2017-01-05 23:26:45 +03:00
|
|
|
Promise
|
|
|
|
.resolve(0)
|
|
|
|
.then(function(num) {
|
|
|
|
return Promise.resolve(Promise.resolve(\"asdf\"));
|
|
|
|
})
|
|
|
|
.then(function(str) {
|
|
|
|
var a: string = str;
|
2017-01-10 05:49:06 +03:00
|
|
|
var b: number = str; // Error: string ~> number
|
2017-01-05 23:26:45 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// TODO: resolvedPromise.then(<throw(T)>) -> catch(T)
|
2017-01-05 23:26:45 +03:00
|
|
|
Promise
|
|
|
|
.resolve(0)
|
|
|
|
.then(function(num) {
|
|
|
|
throw \"str\";
|
|
|
|
})
|
|
|
|
.catch(function(str) {
|
|
|
|
var a: string = str;
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// TODO
|
|
|
|
var b: number = str; // Error: string ~> number
|
2017-01-05 23:26:45 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
///////////////////////////////////
|
|
|
|
// == Promise.prototype.catch == //
|
|
|
|
///////////////////////////////////
|
2017-01-27 22:05:41 +03:00
|
|
|
|
2017-01-10 05:49:06 +03:00
|
|
|
// rejectedPromise.catch():U -> then(U)
|
2017-01-05 23:26:45 +03:00
|
|
|
Promise
|
|
|
|
.reject(0)
|
|
|
|
.catch(function(num) {
|
|
|
|
return \"asdf\";
|
|
|
|
})
|
|
|
|
.then(function(str) {
|
|
|
|
var a: string = str;
|
2017-01-10 05:49:06 +03:00
|
|
|
var b: number = str; // Error: string ~> number
|
2017-01-05 23:26:45 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// rejectedPromise.catch():Promise<U> -> then(U)
|
2017-01-05 23:26:45 +03:00
|
|
|
Promise
|
|
|
|
.reject(0)
|
|
|
|
.catch(function(num) {
|
|
|
|
return Promise.resolve(\"asdf\");
|
|
|
|
})
|
|
|
|
.then(function(str) {
|
|
|
|
var a: string = str;
|
2017-01-10 05:49:06 +03:00
|
|
|
var b: number = str; // Error: string ~> number
|
2017-01-05 23:26:45 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// rejectedPromise.catch():Promise<Promise<U>> -> then(U)
|
2017-01-05 23:26:45 +03:00
|
|
|
Promise
|
|
|
|
.reject(0)
|
|
|
|
.catch(function(num) {
|
|
|
|
return Promise.resolve(Promise.resolve(\"asdf\"));
|
|
|
|
})
|
|
|
|
.then(function(str) {
|
|
|
|
var a: string = str;
|
2017-01-10 05:49:06 +03:00
|
|
|
var b: number = str; // Error: string ~> number
|
2017-01-05 23:26:45 +03:00
|
|
|
});
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// TODO: resolvedPromise<T> -> catch() -> then():T
|
2017-01-05 23:26:45 +03:00
|
|
|
Promise
|
|
|
|
.resolve(0)
|
2017-01-24 20:37:01 +03:00
|
|
|
.catch(function(err) {})
|
2017-01-05 23:26:45 +03:00
|
|
|
.then(function(num) {
|
|
|
|
var a: number = num;
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// TODO
|
|
|
|
var b: string = num; // Error: string ~> number
|
2017-01-11 18:16:38 +03:00
|
|
|
});
|
|
|
|
"
|
2016-12-23 22:31:38 +03:00
|
|
|
`;
|
|
|
|
|
|
|
|
exports[`test resolve_global.js 1`] = `
|
|
|
|
"/**
|
|
|
|
* test Promise name resolution
|
|
|
|
* @flow
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 1. introduce shadowing bindings for important names
|
|
|
|
*/
|
|
|
|
class Promise {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 2. implicit refs to Promise during desugaring should be unaffected
|
|
|
|
*/
|
|
|
|
async function foo(x: boolean) {
|
|
|
|
if (x) {
|
2016-12-30 19:56:42 +03:00
|
|
|
return {bar: \'baz\'};
|
2016-12-23 22:31:38 +03:00
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function run() {
|
|
|
|
console.log(await foo(true));
|
|
|
|
console.log(await foo(false));
|
|
|
|
}
|
|
|
|
|
|
|
|
run();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 3. but explicit name refs from code and annos resolve
|
|
|
|
* using the usual rules
|
|
|
|
*/
|
|
|
|
// error: \`Promise\` in return expr is the local binding
|
|
|
|
async function bar() {
|
|
|
|
return Promise.resolve(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// error: return type anno is a ref to the local binding
|
|
|
|
async function baz(): Promise<number> {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2016-12-27 21:29:31 +03:00
|
|
|
/**
|
|
|
|
* test Promise name resolution
|
|
|
|
* @flow
|
|
|
|
*/
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2016-12-27 21:29:31 +03:00
|
|
|
/**
|
|
|
|
* 1. introduce shadowing bindings for important names
|
|
|
|
*/
|
2017-01-10 05:49:06 +03:00
|
|
|
class Promise {}
|
|
|
|
|
2016-12-27 21:29:31 +03:00
|
|
|
/**
|
|
|
|
* 2. implicit refs to Promise during desugaring should be unaffected
|
|
|
|
*/
|
|
|
|
async function foo(x: boolean) {
|
|
|
|
if (x) {
|
2016-12-30 19:56:42 +03:00
|
|
|
return { bar: \"baz\" };
|
2016-12-27 21:29:31 +03:00
|
|
|
} else {
|
2016-12-28 05:40:04 +03:00
|
|
|
return null;
|
2016-12-27 21:29:31 +03:00
|
|
|
}
|
|
|
|
}
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2016-12-27 21:29:31 +03:00
|
|
|
async function run() {
|
2016-12-28 05:40:04 +03:00
|
|
|
console.log(await foo(true));
|
|
|
|
console.log(await foo(false));
|
2016-12-27 21:29:31 +03:00
|
|
|
}
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2016-12-27 21:29:31 +03:00
|
|
|
run();
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 3. but explicit name refs from code and annos resolve
|
|
|
|
* using the usual rules
|
|
|
|
*/
|
|
|
|
// error: \`Promise\` in return expr is the local binding
|
2016-12-27 21:29:31 +03:00
|
|
|
async function bar() {
|
2016-12-28 05:40:04 +03:00
|
|
|
return Promise.resolve(0);
|
2016-12-27 21:29:31 +03:00
|
|
|
}
|
2017-01-10 05:49:06 +03:00
|
|
|
|
|
|
|
// error: return type anno is a ref to the local binding
|
2016-12-27 21:29:31 +03:00
|
|
|
async function baz(): Promise<number> {
|
2016-12-28 05:40:04 +03:00
|
|
|
return 0;
|
2017-01-11 18:16:38 +03:00
|
|
|
}
|
|
|
|
"
|
2016-12-23 22:31:38 +03:00
|
|
|
`;
|
|
|
|
|
|
|
|
exports[`test resolve_void.js 1`] = `
|
|
|
|
"// @flow
|
|
|
|
|
|
|
|
(Promise.resolve(): Promise<number>); // error
|
|
|
|
|
|
|
|
(Promise.resolve(undefined): Promise<number>); // error
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2016-12-27 21:29:31 +03:00
|
|
|
// @flow
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2017-01-26 22:57:43 +03:00
|
|
|
(Promise.resolve(): Promise<number>); // error
|
2017-01-11 18:16:38 +03:00
|
|
|
(Promise.resolve(undefined): Promise<number>); // error
|
|
|
|
"
|
2016-12-23 22:31:38 +03:00
|
|
|
`;
|