Skip to content

String literal function overloads not working as expected #11089

@geoffreak

Description

@geoffreak

I ran into an issue today with string literal function overloads using Typescript 2.0.3 while trying to write a library for Sift Science. I was attempting to create a function with stricter object checking when called with a certain string first. I was a bit surprised this doesn't work in a way I had expected.

async function addEvent(eventType: '$login', email: string | undefined, data: LoginEvent): Promise<void | Error>;
async function addEvent(eventType: '$logout', email: string, data?: LogoutEvent): Promise<void | Error>;
async function addEvent(eventType: string, email: string | undefined, data: Object = {}): Promise<void | Error> {
  // ...
}

interface SiftScienceBaseEvent {
  $ip?: string;
  $time?: number;
}
interface LoginEvent extends SiftScienceBaseEvent {
  $session_id: string;
  $login_status: '$success' | '$failure';
}
interface LogoutEvent extends SiftScienceBaseEvent {
  // This page intentionally left blank
}

let sid: string | undefined;
addEvent('$login', undefined, {
  $login_status: '$success',
  $session_id: sid,
});

The error I expected to see: (and you can indeed see by commenting out the $logout overload)

Types of property $session_id are incompatible

The error I see instead:

Argument of type '"$login"' is not assignable to parameter of type '"$logout"'

I had assumed that the string literal as the first parameter would specify which overload to use, but it seems that only the object types really work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already createdNeeds More InfoThe issue still hasn't been fully clarified

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions