Merge pull request #10103 from Microsoft/narrowing-a-type-parameter-intersects-concrete-types
Correctly narrow unconstrained type parameters
This commit is contained in:
commit
acfdfe0560
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue