声明的类在typescript中中断类型检查

声明的类在typescript中中断类型检查,typescript,Typescript,我正在尝试键入一个回调,我想我已经成功了。但我刚刚意识到,我最近在添加“declare类”时打破了我的定义 在下面的代码中,我不希望1作为ValidationError或Error被接受,但是我没有得到ValidationError的警告,为什么不呢 类型CallbackBroken={ (错误:ValidationError):无效; (错误:null,值:string):void; } 类型回调工作={ (错误:error):无效; (错误:null,值:string):void; }

我正在尝试键入一个回调,我想我已经成功了。但我刚刚意识到,我最近在添加“declare类”时打破了我的定义

在下面的代码中,我不希望1作为
ValidationError
Error
被接受,但是我没有得到
ValidationError
的警告,为什么不呢

类型CallbackBroken={
(错误:ValidationError):无效;
(错误:null,值:string):void;
}
类型回调工作={
(错误:error):无效;
(错误:null,值:string):void;
}
函数doThings1(c:CallbackBroken){
c(空,'b');
c(1);
}
函数doThings2(c:回调工作){
c(空,'b');
c(1);
}
声明类ValidationError{
建造商(错误代码:编号);

}
实例类型
ValidationError
是带有
{}
,因为您没有为它声明任何实例属性,并且当编译器检查某个值是否与类兼容时。由于
1
是一个有效的
{}
,因此它编译得很好

编辑:
{}
类型是“空类型”或“空接口”。它没有声明的属性,这对满足它的值几乎没有限制。(只有
null
undefined
{}
不兼容)。在TypeScript中,一种类型的值是
a
B
类型的变量,如:

declare const a: A; // value of type A
const b: B = a; // assigned to variable of type B
如果类型
B
中声明的所有属性等于类型
A
中相同命名属性(或其子类型)。如果
B
{}
,则在任何类型的
a
中都找不到一个冲突的属性。所以这很好:

const a = 1;  // value of type 1, has all the properties of Number instances
const b: {} = a; // assigned to variable of type {}.
然而,反过来也不好:

const a = {}; // value of type {}
const b: 1 = a; // error, Type '{}' is not assignable to type '1'.

ValidationError
是否有任何方法或属性?如果您在类声明中添加一个,它应该可以解决您的问题。例如,如果
ValidationError
实现了
Error
,则可以将其更改为:

declare class ValidationError implements Error {
    constructor(errorCode: number);
    name: string;
    message: string;
    stack?: string;
}
或者如@err1100所示,由于
Error
也是
Error
对象的构造函数的名称,因此:

declare class ValidationError extends Error {
    constructor(errorCode: number);
}
它的行为应该和你期望的一样


希望有帮助;祝你好运

实例类型
ValidationError
是带有
{}
,因为您没有为它声明任何实例属性,并且当编译器检查某个值是否与类兼容时。由于
1
是一个有效的
{}
,因此它编译得很好

编辑:
{}
类型是“空类型”或“空接口”。它没有声明的属性,这对满足它的值几乎没有限制。(只有
null
undefined
{}
不兼容)。在TypeScript中,一种类型的值是
a
B
类型的变量,如:

declare const a: A; // value of type A
const b: B = a; // assigned to variable of type B
如果类型
B
中声明的所有属性等于类型
A
中相同命名属性(或其子类型)。如果
B
{}
,则在任何类型的
a
中都找不到一个冲突的属性。所以这很好:

const a = 1;  // value of type 1, has all the properties of Number instances
const b: {} = a; // assigned to variable of type {}.
然而,反过来也不好:

const a = {}; // value of type {}
const b: 1 = a; // error, Type '{}' is not assignable to type '1'.

ValidationError
是否有任何方法或属性?如果您在类声明中添加一个,它应该可以解决您的问题。例如,如果
ValidationError
实现了
Error
,则可以将其更改为:

declare class ValidationError implements Error {
    constructor(errorCode: number);
    name: string;
    message: string;
    stack?: string;
}
或者如@err1100所示,由于
Error
也是
Error
对象的构造函数的名称,因此:

declare class ValidationError extends Error {
    constructor(errorCode: number);
}
它的行为应该和你期望的一样


希望有帮助;祝你好运

除了自己添加实例成员之外,另一种方法是声明类扩展
Error
声明类ValidationError扩展Error{}
。我想我理解了结构兼容性,但我不理解为什么“1是有效的{}”。我非常确定ValidationError确实扩展了错误(我不确定如何检查,因为我只能在运行时访问对象),所以这听起来是一个不错的解决方案。
{}
是“空接口”或“空类型”,它与几乎任何东西都兼容(除了
null
未定义的
)。这是一个非常大的框,几乎可以容纳值。为“
1
是一个有效的
{}
”添加了一些解释。我猜这是一个单独的问题,所以我把它作为一个新的发布了:但它可能与此相关。除了自己添加实例成员之外,另一个选择就是声明类扩展
Error
声明类ValidationError扩展Error{}
。我想我理解了结构兼容性,但我不理解为什么“1是有效的{}”。我非常确定ValidationError确实扩展了错误(我不确定如何检查,因为我只能在运行时访问对象),所以这听起来是一个不错的解决方案。
{}
是“空接口”或“空类型”,它与几乎任何东西都兼容(除了
null
未定义的
)。这是一个非常大的框,几乎可以容纳值。为“
1
是一个有效的
{}
”添加了一些解释。我猜这是一个单独的问题,所以我将其作为一个新问题发布:但它可能与此相关。