TypeScript 无法编译,因为“any"的类型声明失去了类型安全性 [英] TypeScript Failed to compile because Type declaration of 'any' loses type-safety
问题描述
我应该如何解决以下错误消息:
<块引用>未能编译/.../SoftwareLicenseCodes/index.tsx (14,20): 类型'any' 的声明失去了类型安全性.考虑用一个替换它更精确的类型.此错误发生在构建时间和不能被解雇.
查看以下代码:
import * as React from 'react';导入'./SoftwareLicenseCodes.css';界面 SoftwareLicenseCodesProps {}界面 SoftwareLicenseCodesState {计数:字符串;oneTimeUsage:布尔值;持续时间:字符串;有效从:字符串;有效到:字符串;分配器:字符串;[键:字符串]:任何;}类 SoftwareLicenseCodes 扩展了 React.Component{构造函数(道具:SoftwareLicenseCodesProps){超级(道具);this.state = {经销商:'',数数:'',oneTimeUsage:假,期间: '',有效发件人:'',有效: ''};this.onInputChange = this.onInputChange.bind(this);}handleSubmit(事件:React.FormEvent){警报('提交');event.preventDefault();}onInputChange = (事件: React.FormEvent) =>{const value = event.currentTarget.type === 'checkbox' ?event.currentTarget.checked : event.currentTarget.value;this.setState({[名称]:值});}使成为() {返回 (<div className="user-container software-codes"><div className="user-single-container"><h1>软件许可代码</h1><form className="software-codes__form";onSubmit={this.handleSubmit}><标签><span className="software-codes__input-element">Count</span><输入名称=计数"类型=数字"值={this.state.count}/>标签><标签><span className="software-codes__input-element">Distributor</span><输入名称=经销商"类型=文本"值={this.state.distributor}/>标签><标签><span className="software-codes__input-element">一次使用</span><输入名称=oneTimeUsage";类型=复选框"选中={this.state.oneTimeUsage}/>标签><标签><span className="software-codes__input-element">持续时间</span><输入名称=持续时间"类型=数字"值={this.state.duration}/>标签><input className="software-codes__input-element";类型=提交"值=提交"/></表单>
);}}导出默认的 SoftwareLicenseCodes;
您的代码仅设置字符串或布尔值,因此您可以将其锁定更多:
interface SoftwareLicenseCodesState {计数:字符串;oneTimeUsage:布尔值;持续时间:字符串;有效从:字符串;有效到:字符串;分配器:字符串;[key: string]: string|boolean;//------------^^^^^^^^^^^^^^^}
或者,如果您想要完全类型安全,您可以删除字符串索引签名并编写额外的代码来打开输入名称,然后使用显式属性名称.这可以最大限度地利用类型检查,同时(显然)增加代码大小/复杂性:
function setNamed(target: SoftwareLicenseCodesState, name: string, value: string|boolean): SoftwareLicenseCodesState {if (name === "oneTimeUsage") {//可能在这里添加断言值是一个布尔值target.oneTimeUsage = 布尔值;} 别的 {//可能在这里添加断言值是一个字符串const strValue = 字符串形式的值;开关(名称){案例计数":target.count = strValue;休息;案例持续时间":target.duration = strValue;休息;案例validFrom":target.validFrom = strValue;休息;案例validTo":target.validTo = strValue;休息;案例经销商":target.distributor = strValue;休息;默认://这里断言失败}}返回目标;}
然后
this.setState(setNamed({}, name, value));
笨手笨脚,但最大限度地进行类型检查.
我真的很想找到一种方法让你使用 索引类型,但名称来自 input
元素的 name
属性,如果没有 开关,我无法看到如何做到这一点
以上.这让我很困扰,因为我似乎记得使用 keyof
为名称构建联合类型的一些超级聪明的方法......
How should I address the following error message:
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.
See the following code:
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;
Your code only sets either string or boolean values, so you could lock it down a bit more:
interface SoftwareLicenseCodesState {
count: string;
oneTimeUsage: boolean;
duration: string;
validFrom: string;
validTo: string;
distributor: string;
[key: string]: string|boolean;
// ------------^^^^^^^^^^^^^^
}
Alternately, if you want to have full type safety, you could remove the string index signature and write extra code that switches on the name of the input and then uses an explicit property name. That maximizes your use of type-checking, while (obviously) increasing code 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;
}
Then
this.setState(setNamed({}, name, value));
Clumsy as all get-out, but maximizes type-checking.
I really want to find a way for you to use index types, but with the name coming from the name
property of an input
element, I can't see how to do that without the switch
above. Which bothers me, because I seem to recall some uber-clever way of using keyof
to build a union type for the name...
这篇关于TypeScript 无法编译,因为“any"的类型声明失去了类型安全性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!