TypeScript 编译失败,因为 'any' 的类型声明失去类型安全
TypeScript Failed to compile because Type declaration of 'any' loses type-safety
我应该如何解决以下错误消息:
Failed to compile /.../SoftwareLicenseCodes/index.tsx (14,20): Type
declaration of 'any' loses type-safety. Consider replacing it with a
more precise type. This error occurred during the build time and
cannot be dismissed.
见以下代码:
import * as React from 'react';
import './SoftwareLicenseCodes.css';
interface SoftwareLicenseCodesProps {
}
interface SoftwareLicenseCodesState {
count: string;
oneTimeUsage: boolean;
duration: string;
validFrom: string;
validTo: string;
distributor: string;
[key: string]: any;
}
class SoftwareLicenseCodes extends React.Component<SoftwareLicenseCodesProps, SoftwareLicenseCodesState> {
constructor(props: SoftwareLicenseCodesProps) {
super(props);
this.state = {
distributor: '',
count:'',
oneTimeUsage: false,
duration: '',
validFrom: '',
validTo: ''
};
this.onInputChange = this.onInputChange.bind(this);
}
handleSubmit(event: React.FormEvent<HTMLFormElement>) {
alert('submit');
event.preventDefault();
}
onInputChange = (event: React.FormEvent<HTMLInputElement>) => {
const value = event.currentTarget.type === 'checkbox' ? event.currentTarget.checked : event.currentTarget.value;
this.setState({
[name]: value
});
}
render() {
return (
<div className="user-container software-codes">
<div className="user-single-container">
<h1>Software License Codes</h1>
<form className="software-codes__form" onSubmit={this.handleSubmit}>
<label>
<span className="software-codes__input-element">Count</span>
<input
name="count"
type="number"
value={this.state.count}
/>
</label>
<label>
<span className="software-codes__input-element">Distributor</span>
<input
name="distributor"
type="text"
value={this.state.distributor}
/>
</label>
<label>
<span className="software-codes__input-element">One time usage</span>
<input
name="oneTimeUsage"
type="checkbox"
checked={this.state.oneTimeUsage}
/>
</label>
<label>
<span className="software-codes__input-element">Duration</span>
<input
name="duration"
type="number"
value={this.state.duration}
/>
</label>
<input className="software-codes__input-element" type="submit" value="Submit" />
</form>
</div>
</div>
);
}
}
export default SoftwareLicenseCodes;
您的代码仅设置字符串或布尔值,因此您可以将其锁定得更多一些:
interface SoftwareLicenseCodesState {
count: string;
oneTimeUsage: boolean;
duration: string;
validFrom: string;
validTo: string;
distributor: string;
[key: string]: string|boolean;
// ------------^^^^^^^^^^^^^^
}
或者,如果您想要完全类型安全,您可以删除字符串索引签名并编写额外的代码来切换输入名称,然后使用显式 属性 名称。这最大限度地利用了类型检查,同时(显然)增加了代码 size/complexity:
function setNamed(target: SoftwareLicenseCodesState, name: string, value: string|boolean): SoftwareLicenseCodesState {
if (name === "oneTimeUsage") {
// Probably add assertion here that value is a boolean
target.oneTimeUsage = value as boolean;
} else {
// Probably add assertion here that value is a string
const strValue = value as string;
switch (name) {
case "count":
target.count = strValue;
break;
case "duration":
target.duration = strValue;
break;
case "validFrom":
target.validFrom = strValue;
break;
case "validTo":
target.validTo = strValue;
break;
case "distributor":
target.distributor = strValue;
break;
default:
// Failed assertion here
}
}
return target;
}
然后
this.setState(setNamed({}, name, value));
虽然笨拙,但最大限度地进行了类型检查。
我真的很想找到一种方法供您使用 index types,但是名称来自 input
元素的 name
属性,我可以如果没有上面的 switch
,请看如何做到这一点。这让我很困扰,因为我似乎记得一些使用 keyof
为名称构建联合类型的超级聪明的方法...
您可以禁用此 TSLint 规则,但我不知道它有多安全:
interface SoftwareLicenseCodesState {
count: string;
oneTimeUsage: boolean;
duration: string;
validFrom: string;
validTo: string;
distributor: string;
// tslint:disable-next-line: no-any
[key: string]: any;
}
有时您需要使用any
。例如,当您覆盖 HttpInterceptor
class 的 intercept()
方法时:https://angular.io/api/common/http/HttpInterceptor
我个人禁用了这条规则。为此,进入你的 tslint.json
文件并评论这一行:
// "no-any": true,
我应该如何解决以下错误消息:
Failed to compile /.../SoftwareLicenseCodes/index.tsx (14,20): Type declaration of 'any' loses type-safety. Consider replacing it with a more precise type. This error occurred during the build time and cannot be dismissed.
见以下代码:
import * as React from 'react';
import './SoftwareLicenseCodes.css';
interface SoftwareLicenseCodesProps {
}
interface SoftwareLicenseCodesState {
count: string;
oneTimeUsage: boolean;
duration: string;
validFrom: string;
validTo: string;
distributor: string;
[key: string]: any;
}
class SoftwareLicenseCodes extends React.Component<SoftwareLicenseCodesProps, SoftwareLicenseCodesState> {
constructor(props: SoftwareLicenseCodesProps) {
super(props);
this.state = {
distributor: '',
count:'',
oneTimeUsage: false,
duration: '',
validFrom: '',
validTo: ''
};
this.onInputChange = this.onInputChange.bind(this);
}
handleSubmit(event: React.FormEvent<HTMLFormElement>) {
alert('submit');
event.preventDefault();
}
onInputChange = (event: React.FormEvent<HTMLInputElement>) => {
const value = event.currentTarget.type === 'checkbox' ? event.currentTarget.checked : event.currentTarget.value;
this.setState({
[name]: value
});
}
render() {
return (
<div className="user-container software-codes">
<div className="user-single-container">
<h1>Software License Codes</h1>
<form className="software-codes__form" onSubmit={this.handleSubmit}>
<label>
<span className="software-codes__input-element">Count</span>
<input
name="count"
type="number"
value={this.state.count}
/>
</label>
<label>
<span className="software-codes__input-element">Distributor</span>
<input
name="distributor"
type="text"
value={this.state.distributor}
/>
</label>
<label>
<span className="software-codes__input-element">One time usage</span>
<input
name="oneTimeUsage"
type="checkbox"
checked={this.state.oneTimeUsage}
/>
</label>
<label>
<span className="software-codes__input-element">Duration</span>
<input
name="duration"
type="number"
value={this.state.duration}
/>
</label>
<input className="software-codes__input-element" type="submit" value="Submit" />
</form>
</div>
</div>
);
}
}
export default SoftwareLicenseCodes;
您的代码仅设置字符串或布尔值,因此您可以将其锁定得更多一些:
interface SoftwareLicenseCodesState {
count: string;
oneTimeUsage: boolean;
duration: string;
validFrom: string;
validTo: string;
distributor: string;
[key: string]: string|boolean;
// ------------^^^^^^^^^^^^^^
}
或者,如果您想要完全类型安全,您可以删除字符串索引签名并编写额外的代码来切换输入名称,然后使用显式 属性 名称。这最大限度地利用了类型检查,同时(显然)增加了代码 size/complexity:
function setNamed(target: SoftwareLicenseCodesState, name: string, value: string|boolean): SoftwareLicenseCodesState {
if (name === "oneTimeUsage") {
// Probably add assertion here that value is a boolean
target.oneTimeUsage = value as boolean;
} else {
// Probably add assertion here that value is a string
const strValue = value as string;
switch (name) {
case "count":
target.count = strValue;
break;
case "duration":
target.duration = strValue;
break;
case "validFrom":
target.validFrom = strValue;
break;
case "validTo":
target.validTo = strValue;
break;
case "distributor":
target.distributor = strValue;
break;
default:
// Failed assertion here
}
}
return target;
}
然后
this.setState(setNamed({}, name, value));
虽然笨拙,但最大限度地进行了类型检查。
我真的很想找到一种方法供您使用 index types,但是名称来自 input
元素的 name
属性,我可以如果没有上面的 switch
,请看如何做到这一点。这让我很困扰,因为我似乎记得一些使用 keyof
为名称构建联合类型的超级聪明的方法...
您可以禁用此 TSLint 规则,但我不知道它有多安全:
interface SoftwareLicenseCodesState {
count: string;
oneTimeUsage: boolean;
duration: string;
validFrom: string;
validTo: string;
distributor: string;
// tslint:disable-next-line: no-any
[key: string]: any;
}
有时您需要使用any
。例如,当您覆盖 HttpInterceptor
class 的 intercept()
方法时:https://angular.io/api/common/http/HttpInterceptor
我个人禁用了这条规则。为此,进入你的 tslint.json
文件并评论这一行:
// "no-any": true,