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) {
|
if (flags & TypeFlags.TypeParameter) {
|
||||||
const constraint = getConstraintOfTypeParameter(<TypeParameter>type);
|
const constraint = getConstraintOfTypeParameter(<TypeParameter>type);
|
||||||
return constraint ? getTypeFacts(constraint) : TypeFacts.All;
|
return getTypeFacts(constraint || emptyObjectType);
|
||||||
}
|
}
|
||||||
if (flags & TypeFlags.UnionOrIntersection) {
|
if (flags & TypeFlags.UnionOrIntersection) {
|
||||||
return getTypeFactsOfTypes((<UnionOrIntersectionType>type).types);
|
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) {
|
function getTypeWithDefault(type: Type, defaultExpression: Expression) {
|
||||||
|
|
|
@ -35,6 +35,22 @@ function b() {
|
||||||
}
|
}
|
||||||
x; // string
|
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]
|
//// [controlFlowIfStatement.js]
|
||||||
|
@ -72,3 +88,19 @@ function b() {
|
||||||
}
|
}
|
||||||
x; // string
|
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; // string
|
||||||
>x : Symbol(x, Decl(controlFlowIfStatement.ts, 26, 7))
|
>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
|
||||||
>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
|
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