Skip to content

Type guards not working when using partial mapped types. #28434

Closed
@willchapin

Description

@willchapin

TypeScript Version: 3.1.3

Search Terms:
Type Guards, Partial

Code

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 '';
}

Expected behavior:
Successful compilation of the above code with tsc --strictNullChecks

Actual behavior:
Compilation fails with error TS2339: Property 'name' does not exist on type '{}'.
Interestingly, replacing type PartialUser = Partial<User>; with

type PartialUser = {
  email?: string;
  name?: string;
};

works as expected. Shouldn't these two definitions of PartialUser be functionally equivalent?

Playground Link:
https://agentcooper.github.io/typescript-play/?noImplicitAny=false&strictFunctionTypes=false&strictPropertyInitialization=false&noImplicitThis=false&noImplicitReturns=false&alwaysStrict=false#code/C4TwDgpgBA8gRgKygXigbwL5QD5QK4B2AJhAGYCWBERA3AFB2iRQCqAzhAE4rp1T9QIAWwCG5ADYAuKG2CdKAc3oCoBEUIjTZ8gkroZ6jcNAAKIzsHIjx7LjzMWr4gDy3OAPkMB6L1CanzS2s3HjQ6HwFhMXEAfi05RXoI-jUNOJkE3STfAwZSQgBjSwB7AihyNjcACmLEaXgEAEppWqQKqAcgmw5uMP5OCGA8TjK5PAh6DDzCkrKFQbcAOXUIGrrYREbefnJSKCqK6tbGrb6BAaGRqFaAOlSJvigpx4vhsoByd8mgA

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptDomain: Control FlowThe issue relates to control flow analysisDomain: Mapped TypesThe issue relates to mapped types

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions