mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Merge pull request #29847 from Microsoft/inferToUnionTypes
Improve inference to union and intersection types
This commit is contained in:
commit
f93f4f3c62
@ -14473,26 +14473,15 @@ namespace ts {
|
||||
inferFromTypes(source, getUnionType([getTrueTypeFromConditionalType(<ConditionalType>target), getFalseTypeFromConditionalType(<ConditionalType>target)]));
|
||||
}
|
||||
else if (target.flags & TypeFlags.UnionOrIntersection) {
|
||||
const targetTypes = (<UnionOrIntersectionType>target).types;
|
||||
let typeVariableCount = 0;
|
||||
let typeVariable: TypeParameter | IndexedAccessType | undefined;
|
||||
// First infer to each type in union or intersection that isn't a type variable
|
||||
for (const t of targetTypes) {
|
||||
if (getInferenceInfoForType(t)) {
|
||||
typeVariable = <InstantiableType>t;
|
||||
typeVariableCount++;
|
||||
}
|
||||
else {
|
||||
inferFromTypes(source, t);
|
||||
}
|
||||
}
|
||||
// Next, if target containings a single naked type variable, make a secondary inference to that type
|
||||
// variable. This gives meaningful results for union types in co-variant positions and intersection
|
||||
// types in contra-variant positions (such as callback parameters).
|
||||
if (typeVariableCount === 1) {
|
||||
for (const t of (<UnionOrIntersectionType>target).types) {
|
||||
const savePriority = priority;
|
||||
priority |= InferencePriority.NakedTypeVariable;
|
||||
inferFromTypes(source, typeVariable!);
|
||||
// Inferences directly to naked type variables are given lower priority as they are
|
||||
// less specific. For example, when inferring from Promise<string> to T | Promise<T>,
|
||||
// we want to infer string for T, not Promise<string> | string.
|
||||
if (getInferenceInfoForType(t)) {
|
||||
priority |= InferencePriority.NakedTypeVariable;
|
||||
}
|
||||
inferFromTypes(source, t);
|
||||
priority = savePriority;
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,9 +120,9 @@ export enum PubSubRecordIsStoredInRedisAsA {
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}> : BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString; }>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) : BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA; }>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) : BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString; }>
|
||||
>buildPubSubRecordType : <SO_FAR>(soFar: SO_FAR) => BuildPubSubRecordType<SO_FAR>
|
||||
>Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}) : SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA; }
|
||||
>Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}) : SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString; }
|
||||
>Object.assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>Object : ObjectConstructor
|
||||
>assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
@ -144,9 +144,9 @@ export enum PubSubRecordIsStoredInRedisAsA {
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}> : BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash; }>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) : BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA; }>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) : BuildPubSubRecordType<SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash; }>
|
||||
>buildPubSubRecordType : <SO_FAR>(soFar: SO_FAR) => BuildPubSubRecordType<SO_FAR>
|
||||
>Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}) : SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA; }
|
||||
>Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}) : SO_FAR & { storedAs: PubSubRecordIsStoredInRedisAsA.redisHash; }
|
||||
>Object.assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>Object : ObjectConstructor
|
||||
>assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
@ -337,16 +337,16 @@ export enum PubSubRecordIsStoredInRedisAsA {
|
||||
|
||||
buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>,
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}> : BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: 0; }>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) : BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: number; }>
|
||||
>buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) : BuildPubSubRecordType<SO_FAR & { maxMsToWaitBeforePublishing: 0; }>
|
||||
>buildPubSubRecordType : <SO_FAR>(soFar: SO_FAR) => BuildPubSubRecordType<SO_FAR>
|
||||
>Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0}) : SO_FAR & { maxMsToWaitBeforePublishing: number; }
|
||||
>Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0}) : SO_FAR & { maxMsToWaitBeforePublishing: 0; }
|
||||
>Object.assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>Object : ObjectConstructor
|
||||
>assign : { <T, U>(target: T, source: U): T & U; <T, U, V>(target: T, source1: U, source2: V): T & U & V; <T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; }
|
||||
>{} : {}
|
||||
>soFar : SO_FAR
|
||||
>{maxMsToWaitBeforePublishing: 0} : { maxMsToWaitBeforePublishing: number; }
|
||||
>maxMsToWaitBeforePublishing : number
|
||||
>{maxMsToWaitBeforePublishing: 0} : { maxMsToWaitBeforePublishing: 0; }
|
||||
>maxMsToWaitBeforePublishing : 0
|
||||
>0 : 0
|
||||
>maxMsToWaitBeforePublishing : 0
|
||||
}
|
||||
|
||||
2
tests/baselines/reference/jqueryInference.js
vendored
2
tests/baselines/reference/jqueryInference.js
vendored
@ -11,7 +11,7 @@ declare function shouldBeIdentity<T, U>(p: DoNothingAlias<T, U>): MyPromise<T, U
|
||||
|
||||
declare const p1: MyPromise<boolean, any>;
|
||||
var p2 = shouldBeIdentity(p1);
|
||||
var p2: MyPromise<boolean, {}>;
|
||||
var p2: MyPromise<boolean, any>;
|
||||
|
||||
|
||||
//// [jqueryInference.js]
|
||||
|
||||
@ -48,7 +48,7 @@ var p2 = shouldBeIdentity(p1);
|
||||
>shouldBeIdentity : Symbol(shouldBeIdentity, Decl(jqueryInference.ts, 6, 58))
|
||||
>p1 : Symbol(p1, Decl(jqueryInference.ts, 10, 13))
|
||||
|
||||
var p2: MyPromise<boolean, {}>;
|
||||
var p2: MyPromise<boolean, any>;
|
||||
>p2 : Symbol(p2, Decl(jqueryInference.ts, 11, 3), Decl(jqueryInference.ts, 12, 3))
|
||||
>MyPromise : Symbol(MyPromise, Decl(jqueryInference.ts, 0, 0))
|
||||
|
||||
|
||||
@ -22,11 +22,11 @@ declare const p1: MyPromise<boolean, any>;
|
||||
>p1 : MyPromise<boolean, any>
|
||||
|
||||
var p2 = shouldBeIdentity(p1);
|
||||
>p2 : MyPromise<boolean, {}>
|
||||
>shouldBeIdentity(p1) : MyPromise<boolean, {}>
|
||||
>p2 : MyPromise<boolean, any>
|
||||
>shouldBeIdentity(p1) : MyPromise<boolean, any>
|
||||
>shouldBeIdentity : <T, U>(p: DoNothingAlias<T, U>) => MyPromise<T, U>
|
||||
>p1 : MyPromise<boolean, any>
|
||||
|
||||
var p2: MyPromise<boolean, {}>;
|
||||
>p2 : MyPromise<boolean, {}>
|
||||
var p2: MyPromise<boolean, any>;
|
||||
>p2 : MyPromise<boolean, any>
|
||||
|
||||
|
||||
@ -602,7 +602,7 @@ let exclusive: { id: string, a: number, b: string, c: string, d: boolean } =
|
||||
>d : boolean
|
||||
|
||||
f({ a: 1, b: 'yes' }, { c: 'no', d: false })
|
||||
>f({ a: 1, b: 'yes' }, { c: 'no', d: false }) : { a: number; b: string; } & { c: string; d: boolean; } & { id: string; }
|
||||
>f({ a: 1, b: 'yes' }, { c: 'no', d: false }) : { a: number; b: string; } & { c: string; d: false; } & { id: string; }
|
||||
>f : <T, U>(t: T, u: U) => T & U & { id: string; }
|
||||
>{ a: 1, b: 'yes' } : { a: number; b: string; }
|
||||
>a : number
|
||||
|
||||
@ -173,7 +173,7 @@ f0([]); // Error
|
||||
>[] : never[]
|
||||
|
||||
f0([1]);
|
||||
>f0([1]) : [number, {}]
|
||||
>f0([1]) : [number, number]
|
||||
>f0 : <T, U>(x: [T, ...U[]]) => [T, U]
|
||||
>[1] : [number]
|
||||
>1 : 1
|
||||
|
||||
@ -71,6 +71,24 @@ declare var mbp: Man & Bear;
|
||||
|
||||
pigify(mbp).oinks; // OK, mbp is treated as Pig
|
||||
pigify(mbp).walks; // Ok, mbp is treated as Man
|
||||
|
||||
// Repros from #29815
|
||||
|
||||
interface ITest {
|
||||
name: 'test'
|
||||
}
|
||||
|
||||
const createTestAsync = (): Promise<ITest> => Promise.resolve().then(() => ({ name: 'test' }))
|
||||
|
||||
const createTest = (): ITest => {
|
||||
return { name: 'test' }
|
||||
}
|
||||
|
||||
declare function f1<T, U>(x: T | U): T | U;
|
||||
declare function f2<T, U>(x: T & U): T & U;
|
||||
|
||||
let x1: string = f1('a');
|
||||
let x2: string = f2('a');
|
||||
|
||||
|
||||
//// [unionAndIntersectionInference1.js]
|
||||
@ -80,7 +98,7 @@ function destructure(something, haveValue, haveY) {
|
||||
return something === y ? haveY(y) : haveValue(something);
|
||||
}
|
||||
var value = Math.random() > 0.5 ? 'hey!' : undefined;
|
||||
var result = destructure(value, function (text) { return 'string'; }, function (y) { return 'other one'; }); // text: string, y: Y
|
||||
var result = destructure(value, text => 'string', y => 'other one'); // text: string, y: Y
|
||||
// Repro from #4212
|
||||
function isVoid(value) {
|
||||
return undefined;
|
||||
@ -107,7 +125,13 @@ function baz1(value) {
|
||||
function get(x) {
|
||||
return null; // just an example
|
||||
}
|
||||
var foo;
|
||||
let foo;
|
||||
get(foo).toUpperCase(); // Ok
|
||||
pigify(mbp).oinks; // OK, mbp is treated as Pig
|
||||
pigify(mbp).walks; // Ok, mbp is treated as Man
|
||||
const createTestAsync = () => Promise.resolve().then(() => ({ name: 'test' }));
|
||||
const createTest = () => {
|
||||
return { name: 'test' };
|
||||
};
|
||||
let x1 = f1('a');
|
||||
let x2 = f2('a');
|
||||
|
||||
@ -50,7 +50,7 @@ function destructure<a, r>(
|
||||
var value = Math.random() > 0.5 ? 'hey!' : <Y>undefined;
|
||||
>value : Symbol(value, Decl(unionAndIntersectionInference1.ts, 12, 3))
|
||||
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
|
||||
>Y : Symbol(Y, Decl(unionAndIntersectionInference1.ts, 0, 0))
|
||||
>undefined : Symbol(undefined)
|
||||
@ -201,3 +201,59 @@ pigify(mbp).walks; // Ok, mbp is treated as Man
|
||||
>mbp : Symbol(mbp, Decl(unionAndIntersectionInference1.ts, 68, 11))
|
||||
>walks : Symbol(Man.walks, Decl(unionAndIntersectionInference1.ts, 55, 15))
|
||||
|
||||
// Repros from #29815
|
||||
|
||||
interface ITest {
|
||||
>ITest : Symbol(ITest, Decl(unionAndIntersectionInference1.ts, 71, 18))
|
||||
|
||||
name: 'test'
|
||||
>name : Symbol(ITest.name, Decl(unionAndIntersectionInference1.ts, 75, 17))
|
||||
}
|
||||
|
||||
const createTestAsync = (): Promise<ITest> => Promise.resolve().then(() => ({ name: 'test' }))
|
||||
>createTestAsync : Symbol(createTestAsync, Decl(unionAndIntersectionInference1.ts, 79, 5))
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>ITest : Symbol(ITest, Decl(unionAndIntersectionInference1.ts, 71, 18))
|
||||
>Promise.resolve().then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
|
||||
>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
|
||||
>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
|
||||
>name : Symbol(name, Decl(unionAndIntersectionInference1.ts, 79, 77))
|
||||
|
||||
const createTest = (): ITest => {
|
||||
>createTest : Symbol(createTest, Decl(unionAndIntersectionInference1.ts, 81, 5))
|
||||
>ITest : Symbol(ITest, Decl(unionAndIntersectionInference1.ts, 71, 18))
|
||||
|
||||
return { name: 'test' }
|
||||
>name : Symbol(name, Decl(unionAndIntersectionInference1.ts, 82, 10))
|
||||
}
|
||||
|
||||
declare function f1<T, U>(x: T | U): T | U;
|
||||
>f1 : Symbol(f1, Decl(unionAndIntersectionInference1.ts, 83, 1))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference1.ts, 85, 20))
|
||||
>U : Symbol(U, Decl(unionAndIntersectionInference1.ts, 85, 22))
|
||||
>x : Symbol(x, Decl(unionAndIntersectionInference1.ts, 85, 26))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference1.ts, 85, 20))
|
||||
>U : Symbol(U, Decl(unionAndIntersectionInference1.ts, 85, 22))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference1.ts, 85, 20))
|
||||
>U : Symbol(U, Decl(unionAndIntersectionInference1.ts, 85, 22))
|
||||
|
||||
declare function f2<T, U>(x: T & U): T & U;
|
||||
>f2 : Symbol(f2, Decl(unionAndIntersectionInference1.ts, 85, 43))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference1.ts, 86, 20))
|
||||
>U : Symbol(U, Decl(unionAndIntersectionInference1.ts, 86, 22))
|
||||
>x : Symbol(x, Decl(unionAndIntersectionInference1.ts, 86, 26))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference1.ts, 86, 20))
|
||||
>U : Symbol(U, Decl(unionAndIntersectionInference1.ts, 86, 22))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference1.ts, 86, 20))
|
||||
>U : Symbol(U, Decl(unionAndIntersectionInference1.ts, 86, 22))
|
||||
|
||||
let x1: string = f1('a');
|
||||
>x1 : Symbol(x1, Decl(unionAndIntersectionInference1.ts, 88, 3))
|
||||
>f1 : Symbol(f1, Decl(unionAndIntersectionInference1.ts, 83, 1))
|
||||
|
||||
let x2: string = f2('a');
|
||||
>x2 : Symbol(x2, Decl(unionAndIntersectionInference1.ts, 89, 3))
|
||||
>f2 : Symbol(f2, Decl(unionAndIntersectionInference1.ts, 85, 43))
|
||||
|
||||
|
||||
@ -179,3 +179,56 @@ pigify(mbp).walks; // Ok, mbp is treated as Man
|
||||
>mbp : Man & Bear
|
||||
>walks : boolean
|
||||
|
||||
// Repros from #29815
|
||||
|
||||
interface ITest {
|
||||
name: 'test'
|
||||
>name : "test"
|
||||
}
|
||||
|
||||
const createTestAsync = (): Promise<ITest> => Promise.resolve().then(() => ({ name: 'test' }))
|
||||
>createTestAsync : () => Promise<ITest>
|
||||
>(): Promise<ITest> => Promise.resolve().then(() => ({ name: 'test' })) : () => Promise<ITest>
|
||||
>Promise.resolve().then(() => ({ name: 'test' })) : Promise<ITest | { name: "test"; }>
|
||||
>Promise.resolve().then : <TResult1 = void, TResult2 = never>(onfulfilled?: (value: void) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>
|
||||
>Promise.resolve() : Promise<void>
|
||||
>Promise.resolve : { <T>(value: T | PromiseLike<T>): Promise<T>; (): Promise<void>; }
|
||||
>Promise : PromiseConstructor
|
||||
>resolve : { <T>(value: T | PromiseLike<T>): Promise<T>; (): Promise<void>; }
|
||||
>then : <TResult1 = void, TResult2 = never>(onfulfilled?: (value: void) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>
|
||||
>() => ({ name: 'test' }) : () => { name: "test"; }
|
||||
>({ name: 'test' }) : { name: "test"; }
|
||||
>{ name: 'test' } : { name: "test"; }
|
||||
>name : "test"
|
||||
>'test' : "test"
|
||||
|
||||
const createTest = (): ITest => {
|
||||
>createTest : () => ITest
|
||||
>(): ITest => { return { name: 'test' }} : () => ITest
|
||||
|
||||
return { name: 'test' }
|
||||
>{ name: 'test' } : { name: "test"; }
|
||||
>name : "test"
|
||||
>'test' : "test"
|
||||
}
|
||||
|
||||
declare function f1<T, U>(x: T | U): T | U;
|
||||
>f1 : <T, U>(x: T | U) => T | U
|
||||
>x : T | U
|
||||
|
||||
declare function f2<T, U>(x: T & U): T & U;
|
||||
>f2 : <T, U>(x: T & U) => T & U
|
||||
>x : T & U
|
||||
|
||||
let x1: string = f1('a');
|
||||
>x1 : string
|
||||
>f1('a') : "a"
|
||||
>f1 : <T, U>(x: T | U) => T | U
|
||||
>'a' : "a"
|
||||
|
||||
let x2: string = f2('a');
|
||||
>x2 : string
|
||||
>f2('a') : "a"
|
||||
>f2 : <T, U>(x: T & U) => T & U
|
||||
>'a' : "a"
|
||||
|
||||
|
||||
@ -10,4 +10,4 @@ declare function shouldBeIdentity<T, U>(p: DoNothingAlias<T, U>): MyPromise<T, U
|
||||
|
||||
declare const p1: MyPromise<boolean, any>;
|
||||
var p2 = shouldBeIdentity(p1);
|
||||
var p2: MyPromise<boolean, {}>;
|
||||
var p2: MyPromise<boolean, any>;
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
// @target: es2015
|
||||
|
||||
// Repro from #2264
|
||||
|
||||
interface Y { 'i am a very certain type': Y }
|
||||
@ -70,3 +72,21 @@ declare var mbp: Man & Bear;
|
||||
|
||||
pigify(mbp).oinks; // OK, mbp is treated as Pig
|
||||
pigify(mbp).walks; // Ok, mbp is treated as Man
|
||||
|
||||
// Repros from #29815
|
||||
|
||||
interface ITest {
|
||||
name: 'test'
|
||||
}
|
||||
|
||||
const createTestAsync = (): Promise<ITest> => Promise.resolve().then(() => ({ name: 'test' }))
|
||||
|
||||
const createTest = (): ITest => {
|
||||
return { name: 'test' }
|
||||
}
|
||||
|
||||
declare function f1<T, U>(x: T | U): T | U;
|
||||
declare function f2<T, U>(x: T & U): T & U;
|
||||
|
||||
let x1: string = f1('a');
|
||||
let x2: string = f2('a');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user