Angular 类型脚本,参数';s型是规避的
我只是偶然发现了以下几点Angular 类型脚本,参数';s型是规避的,angular,typescript,types,Angular,Typescript,Types,我只是偶然发现了以下几点 const myObject = new Object(); myObject['test'] = 'hello'; calc(myObject['test']); function calc(x: number) { console.log(x * 10); } 这是一个非常简单的案例 我的期望是TypeScript至少会在编译时抱怨它找不到具体的类型,但calc需要一个数字 相反,TypeScript根本不会抱怨,控制台中将出现NaN 我在使用angula
const myObject = new Object();
myObject['test'] = 'hello';
calc(myObject['test']);
function calc(x: number) {
console.log(x * 10);
}
这是一个非常简单的案例
我的期望是TypeScript至少会在编译时抱怨它找不到具体的类型,但calc
需要一个数字
相反,TypeScript根本不会抱怨,控制台中将出现NaN
我在使用angular 4和路由数据时第一次注意到这种行为
const routes: Routes = [
{
path: '**',
data: [{error: new ApplicationError('http-status-404', '', HttpErrorStatus.NotFound)}],
component: ApplicationErrorComponent,
resolve: {
error: ApplicationErrorResolve
}
}
];
@Injectable()
export class ApplicationErrorResolve implements Resolve<ApplicationError> {
constructor(private applicationErrorHandler: ApplicationErrorHandler) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): ApplicationError {
if (route.data != null && route.data[0]['error'] instanceof ApplicationError) {
this.applicationErrorHandler.addError(route.data[0]);
return route.data[0];
}
return null;
}
}
// signature of applicationErrorHandler.addError
addError(error: ApplicationError, navigateToErrorPage: boolean = true) {
}
我不明白。为什么这样做有效?
我知道这与any
有关,但为什么myArray
的定义会取代我的方法签名?
这对我来说毫无意义,给人一种虚假的安全感
还有什么办法可以解决这个问题吗?您需要在tsconfig.json
中设置“noImplicitAny”:true
,或者将--noImplicitAny
标志传递给编译器以捕获这些问题
如果启用了noImplicitAny
,编译器将根据calc
检查myObject['test']
的类型。由于它是关闭的,myObject['test']
的类型被视为any
,它禁用所有类型检查,允许将其传递到calc
使用“noImplicitAny”:true
,您的示例将抛出以下错误:
元素隐式具有“any”类型,因为类型“Object”没有
索引签名
类型脚本编译器选项:
当您执行
constmyarray=newarray时,我认为这是因为您使用了括号表示法。尝试myObject.test='hello';计算(肌体试验)
并查看发生了什么。当使用test
作为属性时,它确实起作用。但是我认为我的类型化方法不应该依赖于我如何提供参数。括号表示法是javascript运行时中的一种反射技术。最好声明一个接口并将其类型转换到它。但我不明白为什么TypeScript在编译时不抱怨?我的方法有一个类型化参数,我只提供“something”。为什么这会起作用?我在TypeScript中遗漏了什么吗?@Arikael如果你想检查类型,请停止使用any
。当您需要类型检查时,请始终定义类型。谢谢,这回答了第一部分(简单示例)。但是第二个问题(角度的实际问题)我仍然没有解决。我在问题(下面的编辑部分)中添加了另一个示例,显示了数组的问题。再次感谢,我遇到的问题不是我可以使用ImActuallyNotPresent
。这正是我所期望的,因为any
,但我没想到calc
会接受myArray[0]
或myArray[0]。事实上我不存在
,因为就像你说的,它可能是任何东西,而不仅仅是一个数字。但是我明确告诉calc
s参数x
只接受number
。这就是我不明白的。当我定义参数必须number
时,为什么我可以提供any
作为参数?@Arikaelany
是TypeScript绕过所有类型检查进入完整JS模式并忽略所有编译时检查的方法,包括验证calc
是否有number
参数。我理解这种混乱。在C#这样的语言中,当方法需要string
而没有强制转换时,不能传递类型为object
的变量。但是如果你认为any
与disable all type checks
同义,那就更有意义了。现在我明白了,也许你可以在你的答案中添加你最后的评论,因为disable all type checks
正是我误解/遗漏的。我想知道为什么angular团队决定使用any
作为路由数据,而不是object
const myArray = new Array<any>();
myArray[0] = { name: 'test'};
myArray[1] = { name: 1} ;
// TypeScript doesn't complain
this.calc(myArray[0]);
// TypeScript doesn't complain
this.calc(myArray[0].ImActuallyNotPresent);
function calc(x: number) {
console.log(x * 10);
}
interface MyArrayContent {
someString: string;
someNumber: number
}
const myArray = new Array<MyArrayContent>();
myArray[0] = { someString: 'test', someNumber: 1 };
myArray[1] = { someString: "test2", someNumber: 2};
calc(myArray[0]); // Error
calc(myArray[0].ImActuallyNotPresent); // Error
calc(myArray[0].someString); // Error
calc(myArray[0].someNumber); // No error
function calc(x: number) {
console.log(x * 10);
}