Closed
Description
TypeScript Version: 2.0.10, and 2.1.4
Code
type DocumentID = string
type DataType = {}
type ObjectCallback = (error:Error, result?: DataType) => void
type ArrayCallback = (error:Error, result?: DataType[]) => void
type ObjectOrArrayCallback = (error:Error, result?: DataType | DataType[]) => void
export class Read {
get(_id: DocumentID): DataType {return {}}
// These functions take either a single id, and return a single object,
// or take an array of ids, and return an array of objects.
read(_id: DocumentID): Promise<DataType>
read(_id: DocumentID, done: ObjectCallback): void
read(_ids: DocumentID[]): Promise<DataType[]>
read(_ids: DocumentID[], done: ArrayCallback): void
read(_id_or_ids: DocumentID | DocumentID[], done?: ObjectOrArrayCallback): Promise<DataType> | Promise<DataType[]> | void {
if (done) {
if (Array.isArray(_id_or_ids)) {
done(undefined, [{},{}])
} else if ((typeof _id_or_ids === 'string') && (_id_or_ids.length > 0)){
done(undefined, {})
}
} else {
return this.promisify_read(_id_or_ids) // TS2345
}
}
// swapping the following two lines results in different error messages
promisify_read(_id: DocumentID): Promise<DataType>
promisify_read(_ids: DocumentID[]) : Promise<DataType[]>
promisify_read(_id_or_ids: DocumentID | DocumentID[]): Promise<DataType> | Promise<DataType[]> {
return new Promise((resolve, reject) => {
// TODO: resolve this typing problem
this.read(_id_or_ids, (error, result) => { // TS2345
if (!error) {
resolve(result)
} else {
reject(error)
}
})
})
}
}
Expected behavior:
I believe this code is correct, and should compile without error.
Actual behavior:
Upon compiling with: tsc --module commonjs --target es6 t.ts
the compiler outputs:
t.ts(24,40): error TS2345: Argument of type 'string | string[]' is not assignable to parameter of type 'string[]'.
Type 'string' is not assignable to type 'string[]'.
t.ts(34,23): error TS2345: Argument of type 'string | string[]' is not assignable to parameter of type 'string[]'.
Type 'string' is not assignable to type 'string[]'.
Also, if I switch the order of the first two declarations for promisify_read, the compiler changes its first error by reversing its selected types to:
t.ts(24,40): error TS2345: Argument of type 'string | string[]' is not assignable to parameter of type 'string'.
Type 'string[]' is not assignable to type 'string'.
Since these are all union types, I don't expect any errors.
Have I stumbled across a bug?
I'm familiar with the rule that the first matching declaration is selected, but the first two declarations select different call forms and don't overlap with each other.
Even if the first behavior is due to incorrectly declaring my functions,
the second behavior seems just wrong.