TypeScript 无法编译,因为“any"的类型声明失去了类型安全性 [英] TypeScript Failed to compile because Type declaration of 'any' loses type-safety

查看:26
本文介绍了TypeScript 无法编译,因为“any"的类型声明失去了类型安全性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我应该如何解决以下错误消息:

<块引用>

未能编译/.../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屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆