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

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

问题描述

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

How should I address the 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.

请参见以下代码:

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;
}

然后

this.setState(setNamed({}, name, value));

笨拙,但最大程度地进行类型检查.

Clumsy as all get-out, but maximizes type-checking.

我真的很想为您使用索引类型,但是其名称来自input元素的name属性,如果没有上述switch,我将看不到该怎么做.这让我感到困扰,因为我似乎想起了使用keyof为名称建立联合类型的一些超级方法...

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天全站免登陆