I'm having trouble with a function overload. Compiler keep picking the wrong signature and I'd like to understand why.
Here a snippet that shows the behavior : Typescript Playground. For reference, here's the snippet source :
class Query { }
class QueryInsert extends Query {
constructor(public readonly objects?: any[], public readonly collection?: any) { super(); }
}
class QueryUpdate extends Query {
constructor(public readonly object?: any, public readonly collection?: any, public readonly conditions?: any) { super(); }
}
class QueryShowCollection extends Query { }
class QueryCollectionExists extends Query {
constructor(public readonly collection: any) { super(); }
}
class QueryDescribeCollection extends Query {
constructor(public readonly collection: any) { super(); }
}
class QueryCreateCollection extends Query {
constructor(public readonly collection: any, public readonly columns?: any[], public readonly indexes?: any[]) { super(); }
}
class QueryDropCollection extends Query {
constructor(public readonly collection: any) { super(); }
}
function execute(query: QueryInsert): 'insert'
function execute(query: QueryUpdate): 'update'
function execute(query: QueryShowCollection): 'show'
function execute(query: QueryCollectionExists): 'exists'
function execute(query: QueryDescribeCollection): 'describe'
function execute(query: QueryCreateCollection): 'create'
function execute(query: QueryDropCollection): 'drop'
function execute(query: Query): any {
}
const insert = execute(new QueryInsert());
const update = execute(new QueryUpdate());
const show = execute(new QueryShowCollection());
const exists = execute(new QueryCollectionExists(''));
const describe = execute(new QueryDescribeCollection(''));
const create = execute(new QueryCreateCollection(''));
const drop = execute(new QueryDropCollection(''));
The unexpected behavior is from the constants at the end. insert should report "insert", update, "update", etc.
Right after show, every constants report "show"
. I understand that the compiler pick the signature from function execute(query: QueryShowCollection): 'show' for these constants. If we move down this signature (ex: below the one with QueryDropCollection), it's now function execute(query: QueryCollectionExists): 'exists' that is taken for the rest of the constants.
There is cleary something I'm doing wrong.
"show"?