Make the relationship between partial mapped types and the empty object not apply for subtype relationship (#29384)

This commit is contained in:
Wesley Wigham 2019-01-17 15:42:58 -08:00 committed by GitHub
parent b6ae492009
commit addeff325b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 170 additions and 1 deletions

View File

@ -12677,7 +12677,7 @@ namespace ts {
}
else {
// An empty object type is related to any mapped type that includes a '?' modifier.
if (isPartialMappedType(target) && isEmptyObjectType(source)) {
if (relation !== subtypeRelation && isPartialMappedType(target) && isEmptyObjectType(source)) {
return Ternary.True;
}
if (isGenericMappedType(target)) {

View File

@ -0,0 +1,42 @@
//// [partialTypeNarrowedToByTypeGuard.ts]
type Obj = {} | undefined;
type User = {
email: string;
name: string;
};
type PartialUser = Partial<User>;
// type PartialUser = {
// email?: string;
// name?: string;
// };
function isUser(obj: Obj): obj is PartialUser {
return true;
}
function getUserName(obj: Obj) {
if (isUser(obj)) {
return obj.name;
}
return '';
}
//// [partialTypeNarrowedToByTypeGuard.js]
"use strict";
// type PartialUser = {
// email?: string;
// name?: string;
// };
function isUser(obj) {
return true;
}
function getUserName(obj) {
if (isUser(obj)) {
return obj.name;
}
return '';
}

View File

@ -0,0 +1,52 @@
=== tests/cases/compiler/partialTypeNarrowedToByTypeGuard.ts ===
type Obj = {} | undefined;
>Obj : Symbol(Obj, Decl(partialTypeNarrowedToByTypeGuard.ts, 0, 0))
type User = {
>User : Symbol(User, Decl(partialTypeNarrowedToByTypeGuard.ts, 0, 26))
email: string;
>email : Symbol(email, Decl(partialTypeNarrowedToByTypeGuard.ts, 2, 13))
name: string;
>name : Symbol(name, Decl(partialTypeNarrowedToByTypeGuard.ts, 3, 18))
};
type PartialUser = Partial<User>;
>PartialUser : Symbol(PartialUser, Decl(partialTypeNarrowedToByTypeGuard.ts, 5, 2))
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
>User : Symbol(User, Decl(partialTypeNarrowedToByTypeGuard.ts, 0, 26))
// type PartialUser = {
// email?: string;
// name?: string;
// };
function isUser(obj: Obj): obj is PartialUser {
>isUser : Symbol(isUser, Decl(partialTypeNarrowedToByTypeGuard.ts, 7, 33))
>obj : Symbol(obj, Decl(partialTypeNarrowedToByTypeGuard.ts, 14, 16))
>Obj : Symbol(Obj, Decl(partialTypeNarrowedToByTypeGuard.ts, 0, 0))
>obj : Symbol(obj, Decl(partialTypeNarrowedToByTypeGuard.ts, 14, 16))
>PartialUser : Symbol(PartialUser, Decl(partialTypeNarrowedToByTypeGuard.ts, 5, 2))
return true;
}
function getUserName(obj: Obj) {
>getUserName : Symbol(getUserName, Decl(partialTypeNarrowedToByTypeGuard.ts, 16, 1))
>obj : Symbol(obj, Decl(partialTypeNarrowedToByTypeGuard.ts, 18, 21))
>Obj : Symbol(Obj, Decl(partialTypeNarrowedToByTypeGuard.ts, 0, 0))
if (isUser(obj)) {
>isUser : Symbol(isUser, Decl(partialTypeNarrowedToByTypeGuard.ts, 7, 33))
>obj : Symbol(obj, Decl(partialTypeNarrowedToByTypeGuard.ts, 18, 21))
return obj.name;
>obj.name : Symbol(name, Decl(partialTypeNarrowedToByTypeGuard.ts, 3, 18))
>obj : Symbol(obj, Decl(partialTypeNarrowedToByTypeGuard.ts, 18, 21))
>name : Symbol(name, Decl(partialTypeNarrowedToByTypeGuard.ts, 3, 18))
}
return '';
}

View File

@ -0,0 +1,49 @@
=== tests/cases/compiler/partialTypeNarrowedToByTypeGuard.ts ===
type Obj = {} | undefined;
>Obj : Obj
type User = {
>User : User
email: string;
>email : string
name: string;
>name : string
};
type PartialUser = Partial<User>;
>PartialUser : Partial<User>
// type PartialUser = {
// email?: string;
// name?: string;
// };
function isUser(obj: Obj): obj is PartialUser {
>isUser : (obj: Obj) => obj is Partial<User>
>obj : Obj
return true;
>true : true
}
function getUserName(obj: Obj) {
>getUserName : (obj: Obj) => string | undefined
>obj : Obj
if (isUser(obj)) {
>isUser(obj) : boolean
>isUser : (obj: Obj) => obj is Partial<User>
>obj : Obj
return obj.name;
>obj.name : string | undefined
>obj : Partial<User>
>name : string | undefined
}
return '';
>'' : ""
}

View File

@ -0,0 +1,26 @@
// @strict: true
type Obj = {} | undefined;
type User = {
email: string;
name: string;
};
type PartialUser = Partial<User>;
// type PartialUser = {
// email?: string;
// name?: string;
// };
function isUser(obj: Obj): obj is PartialUser {
return true;
}
function getUserName(obj: Obj) {
if (isUser(obj)) {
return obj.name;
}
return '';
}