Skip to content

Literal narrowing lost without explicit const assertion #39763

Description

TypeScript Version: 3.9.2

Search Terms:
const assertion, literal narrowing

Code

consta1='A1'consta2='A2'constactionCreators={a1: ()=>({type: a1}),a2: (b: number)=>({type: a2, b}),}typeAction=ReturnType<typeofactionCreators[keyoftypeofactionCreators]>exportdefault(state={},action: Action)=>{switch(action.type){casea2: return{...state,b: action.b}default:
returnstate}}

Expected behavior:
Code with literal narrowing should compile, similar to the following code with an explicit const assertion:

consta1='A1'asconstconsta2='A2'asconst...

Actual behavior:
Code does not compile.

Property 'b' does not exist on type '{ type: string; } | { type: string; b: number; }'.
Property 'b' does not exist on type '{ type: string; }'.(2339)

Related Issues:
Might be related to #9998.

Output
consta1='A1';// as constconsta2='A2';// as constconstactionCreators={a1: ()=>({type: a1}),a2: (b)=>({type: a2, b }),};exportdefault(state={},action)=>{switch(action.type){casea2:
returnObject.assign(Object.assign({},state),{b: action.b});default:
returnstate;}};
Compiler Options
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"esModuleInterop": true,
"declaration": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": 2,
"target": "ES2017",
"jsx": "React",
"module": "ESNext"
}
}

Playground Link:Provided

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions