【问题标题】:String or Number values in TypescriptTypescript 中的字符串或数字值
【发布时间】:2016-09-13 10:24:40
【问题描述】:

我正在努力实现的一个例子:

class Test {
    private _folderId: number;
    private _pageId: number;
    private _folderName: string;
    private _pageName: string;

    constructor(pageId: string | number, folderId: string | number){
        this._folderId = (!isNaN(+folderId)) ? folderId : undefined;
        this._pageId = (!isNaN(+pageId)) ? pageId : undefined;
        this._folderName = (isNaN(+folderId)) ? folderId : undefined;
        this._pageName = (isNaN(+pageId)) ? pageId : undefined;
    }
}

不幸的是,这会引发编译器错误:

TS2322:Type 'string | number' is not assignable to type 'number'. Type 'string' is not assignable to type 'number'.

依此类推(每个变量都有类似的错误)。

有什么办法可以解决吗?目前我唯一能做的就是设置页面和文件夹ID以输入任何...

【问题讨论】:

  • 你需要像private _pageId: string | number;这样定义字段并转换值
  • @iberbeu 但这会破坏逻辑,不是吗?我不希望 pageId 是 string | number ,我希望它只是 number
  • 那么你需要以某种方式将其转换为数字。如果您可以接收string | number,您要么想要parseInt 字符串值(您需要在运行时检查类型或.toString()),或者您实际上不想接收string | number
  • 这是个坏主意。 parseInt 将为空字符串值返回 NaN,TypeScript 在编译时不知道 parseInt 是否会返回 NaN。需要进行运行时检查。类型守卫对此无济于事(事实上,它会让事情变得更糟)

标签: javascript typescript


【解决方案1】:

Guenter Guckelsberger 的回答下的评论建议您需要使用像 '123' 这样的字符串作为数字。这是一个解决方案:

/**
* See http://stackoverflow.com/questions/9716468/is-there-any-function-like-isnumeric-in-javascript-to-validate-numbers
*/
function isNumeric(n: any) : n is number | string {
    return !isNaN(parseFloat(n)) && isFinite(n);
}

function intVal(n: number | string): number {
    return typeof n === "number" ? n : parseInt(n, 10);
}

class Test {
    private _folderId: number;
    private _pageId: number;
    private _folderName: string;
    private _pageName: string;

    constructor(pageId: string | number, folderId: string | number) {
        if (isNumeric(folderId))
            this._folderId = intVal(folderId);
        else
            this._folderName = <string>folderId;
        if (isNumeric(pageId))
            this._pageId = intVal(pageId);
        else
            this._pageName = <string>pageId;
    }
}

【讨论】:

    【解决方案2】:

    你应该使用 typeof 操作符,比如

    typeof folderId === "number"
    

    检查数字或字符串。

    【讨论】:

    • 看不懂你的意思:typeof "123" === "number" 为假,而 typeof 123 === "number" 为真
    • 没错,"123"123 都应该评估为数字
    【解决方案3】:

    由于您提到了 pageIdfolderId 的模棱两可的类型,因此打字稿在赋值时无法确定您的变量是数字还是字符串。因此,您需要在分配时指定变量的确切类型。这可以使用类型转换来完成

    您可以将folderIdpageId 类型转换为数字或字符串,如下所示:

    constructor(pageId: string | number, folderId: string | number){
        this._folderId = (!isNaN(+folderId)) ? folderId as number : undefined;
        this._pageId = (!isNaN(+pageId)) ? pageId as number : undefined;
        this._folderName = (isNaN(+folderId)) ? folderId as string : undefined;
        this._pageName = (isNaN(+pageId)) ? pageId as string: undefined;
    }
    

    另一种类型转换方法是&lt;number&gt;folderId&lt;string&gt;folderId。 你也可以去type Guards,如'Paleo's answer中所示

    【讨论】:

    • 这正是我想要的,很抱歉我接受了 Paleo 的回答,只是因为我认为&lt;type&gt;var 对其他开发人员来说会更明显。谢谢!
    • 像你一样,我开始进行类型转换(使用类型保护),但它不正确。使用您的解决方案,'123' 之类的字符串值将存储在 number 类型的变量中。
    • 是的 var 确实更有意义。但是,如果您在 .jsx 文件中编码,如果您使用 var,编辑器会抱怨,这正是 var as type 派上用场的地方
    • @Paleo 不是真的,如果您尝试将字符串 o 分配给类型为 number 的变量,打字稿编译器会报错:Neither type number nor the type string are assignable to each other
    • @NahushFarkande 使用('123', '456') 调用您的构造函数。 !isNaN(+'123') 返回true。然后将字符串值'123'赋给number类型的变量this._folderId
    猜你喜欢
    • 2017-03-29
    • 2017-08-30
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多