Reputation: 4229
I'm trying to type a callback, and I thought I had it working. But I just realized that I recently broke my definitions when I added a "declare class".
In the code below, I wouldn't expect 1 to be acceptable as either of ValidationError
or Error
, but I get no warning for ValidationError
, why not?
type CallbackBroken = {
(error: ValidationError): void;
(error: null, value: string): void;
}
type CallbackWorking = {
(error: Error): void;
(error: null, value: string): void;
}
function doThings1(c: CallbackBroken) {
c(null, 'b');
c(1);
}
function doThings2(c: CallbackWorking) {
c(null, 'b');
c(1);
}
declare class ValidationError {
constructor(errorCode: number);
}
Upvotes: 0
Views: 95
Reputation: 328187
The instance type ValidationError
is structurally compatible with {}
, since you have declared no instance properties for it, and only instance members are checked when the compiler checks if a value is compatible with a class. And since 1
is a valid {}
, it compiles fine.
Edit: The {}
type is the "empty type" or "empty interface". It has no declared properties, which places almost no restrictions on the values that satisfy it. (Only null
and undefined
are not compatible with {}
). In TypeScript, a value of one type is A
to a variable of type B
, as in:
declare const a: A; // value of type A
const b: B = a; // assigned to variable of type B
if all the declared properties in type B
are equal to (or subtypes of) the same-named properties in type A
. If B
is {}
, you won't find a single property in any type A
that conflicts. So this is fine:
const a = 1; // value of type 1, has all the properties of Number instances
const b: {} = a; // assigned to variable of type {}.
The reverse is not fine, though:
const a = {}; // value of type {}
const b: 1 = a; // error, Type '{}' is not assignable to type '1'.
Does a ValidationError
have any methods or properties? If you add one to the class declaration it should fix your problem. For example, if ValidationError
implements Error
, then you can change it to this:
declare class ValidationError implements Error {
constructor(errorCode: number);
name: string;
message: string;
stack?: string;
}
or as @err1100 suggests, since Error
is also the name of a constructor of Error
objects, this:
declare class ValidationError extends Error {
constructor(errorCode: number);
}
And it should behave as you expect.
Hope that helps; good luck!
Upvotes: 2