Merge pull request #10103 from Microsoft/narrowing-a-type-parameter-intersects-concrete-types

Correctly narrow unconstrained type parameters
This commit is contained in:
Nathan Shively-Sanders 2016-08-08 09:22:32 -07:00 committed by GitHub
commit acfdfe0560
5 changed files with 136 additions and 2 deletions

View file

@ -7901,7 +7901,7 @@ namespace ts {
}
if (flags & TypeFlags.TypeParameter) {
const constraint = getConstraintOfTypeParameter(<TypeParameter>type);
return constraint ? getTypeFacts(constraint) : TypeFacts.All;
return getTypeFacts(constraint || emptyObjectType);
}
if (flags & TypeFlags.UnionOrIntersection) {
return getTypeFactsOfTypes((<UnionOrIntersectionType>type).types);
@ -7928,7 +7928,8 @@ namespace ts {
}
}
}
return firstType ? types ? getUnionType(types) : firstType : neverType;
return types ? getUnionType(types) :
firstType ? firstType : neverType;
}
function getTypeWithDefault(type: Type, defaultExpression: Expression) {

View file

@ -35,6 +35,22 @@ function b() {
}
x; // string
}
function c<T>(data: string | T): T {
if (typeof data === 'string') {
return JSON.parse(data);
}
else {
return data;
}
}
function d<T extends string>(data: string | T): never {
if (typeof data === 'string') {
throw new Error('will always happen');
}
else {
return data;
}
}
//// [controlFlowIfStatement.js]
@ -72,3 +88,19 @@ function b() {
}
x; // string
}
function c(data) {
if (typeof data === 'string') {
return JSON.parse(data);
}
else {
return data;
}
}
function d(data) {
if (typeof data === 'string') {
throw new Error('will always happen');
}
else {
return data;
}
}

View file

@ -71,4 +71,42 @@ function b() {
x; // string
>x : Symbol(x, Decl(controlFlowIfStatement.ts, 26, 7))
}
function c<T>(data: string | T): T {
>c : Symbol(c, Decl(controlFlowIfStatement.ts, 35, 1))
>T : Symbol(T, Decl(controlFlowIfStatement.ts, 36, 11))
>data : Symbol(data, Decl(controlFlowIfStatement.ts, 36, 14))
>T : Symbol(T, Decl(controlFlowIfStatement.ts, 36, 11))
>T : Symbol(T, Decl(controlFlowIfStatement.ts, 36, 11))
if (typeof data === 'string') {
>data : Symbol(data, Decl(controlFlowIfStatement.ts, 36, 14))
return JSON.parse(data);
>JSON.parse : Symbol(JSON.parse, Decl(lib.d.ts, --, --))
>JSON : Symbol(JSON, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>parse : Symbol(JSON.parse, Decl(lib.d.ts, --, --))
>data : Symbol(data, Decl(controlFlowIfStatement.ts, 36, 14))
}
else {
return data;
>data : Symbol(data, Decl(controlFlowIfStatement.ts, 36, 14))
}
}
function d<T extends string>(data: string | T): never {
>d : Symbol(d, Decl(controlFlowIfStatement.ts, 43, 1))
>T : Symbol(T, Decl(controlFlowIfStatement.ts, 44, 11))
>data : Symbol(data, Decl(controlFlowIfStatement.ts, 44, 29))
>T : Symbol(T, Decl(controlFlowIfStatement.ts, 44, 11))
if (typeof data === 'string') {
>data : Symbol(data, Decl(controlFlowIfStatement.ts, 44, 29))
throw new Error('will always happen');
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
}
else {
return data;
>data : Symbol(data, Decl(controlFlowIfStatement.ts, 44, 29))
}
}

View file

@ -90,4 +90,51 @@ function b() {
x; // string
>x : string
}
function c<T>(data: string | T): T {
>c : <T>(data: string | T) => T
>T : T
>data : string | T
>T : T
>T : T
if (typeof data === 'string') {
>typeof data === 'string' : boolean
>typeof data : string
>data : string | T
>'string' : "string"
return JSON.parse(data);
>JSON.parse(data) : any
>JSON.parse : (text: string, reviver?: (key: any, value: any) => any) => any
>JSON : JSON
>parse : (text: string, reviver?: (key: any, value: any) => any) => any
>data : string
}
else {
return data;
>data : T
}
}
function d<T extends string>(data: string | T): never {
>d : <T extends string>(data: string | T) => never
>T : T
>data : string | T
>T : T
if (typeof data === 'string') {
>typeof data === 'string' : boolean
>typeof data : string
>data : string | T
>'string' : "string"
throw new Error('will always happen');
>new Error('will always happen') : Error
>Error : ErrorConstructor
>'will always happen' : string
}
else {
return data;
>data : never
}
}

View file

@ -34,3 +34,19 @@ function b() {
}
x; // string
}
function c<T>(data: string | T): T {
if (typeof data === 'string') {
return JSON.parse(data);
}
else {
return data;
}
}
function d<T extends string>(data: string | T): never {
if (typeof data === 'string') {
throw new Error('will always happen');
}
else {
return data;
}
}