Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么我的Typescript "number“字段是字符串?

我有一个这样的Typescript类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    export class Contract {
        constructor (
           public id: string,
           public name: string,
           public spend: number
        ) {}
    }

这是由使用如下中间类的服务加载的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    export class ContractService {
        // the stuff you would expect

        public loadContracts() {
            this.httpService.get(this.contractEndpoint).subscribe((result) => this.createContracts(result));
        }

        private createContracts(contracts: Array<Contract>) {
            for ( let contract of contracts ) {
                console.log("Contract spend is "+contract.spend+": "+( typeof contract.spend));
            }
        }
    }

当我运行它时,在我的控制台中我看到:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 Contract spend is 10000: string 
 Contract spend is 1222: string
 Contract spend is 20001: string

但是,如果我尝试使用parseInt(contract.spend),那么Typescript编译器就会拒绝,因为它知道contract.spend是一个数字,所以在编译时它知道应该是什么值。

我假设我的rest服务中的JSON将spend字段作为引号返回,但它似乎正在以一种默默失败的方式破坏Typescript的核心优势之一。我需要做什么来确保我的数字字段包含一个数字,或者当错误的类型传递给它时,我的代码会失败?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-08-02 09:48:45

TypeScript在编译时工作,但它会编译为JavaScript。因此,在运行时,只剩下很好的旧JS。

这意味着:如果您的服务在TypeScript未知的情况下为contract.spend提供字符串值,TypeScript将无法知晓。

如果您希望在这种情况下利用静态类型,请让TypeScript知道您的HTTP调用的响应体具有哪种类型。然后主动地将响应从响应正文类型转换为您期望的类型。

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type HttpContractResponse = {
    spend: string
}[];

export class ContractService {
    // the stuff you would expect

    constructor(private httpService: HttpService,
                private contractEndpoint = 'http://endpoint.com') {}

    public loadContracts() {
        this.httpService.get<HttpContractResponse>(this.contractEndpoint)
            .subscribe((result) => this.createContracts(result));
    }

    private createContracts(rawContracts: HttpContractResponse) {
        const contracts: Contract[] = rawContracts.map(rc => {return {
            ...rc,
            spend: +rc.spend
        }});
        for (let contract of contracts) {
            console.log('Contract spend is ' + contract.spend + ': ' + (typeof contract.spend));
        }
    }
}
票数 2
EN

Stack Overflow用户

发布于 2019-08-09 09:24:44

我建议你看看typescript-json-validator,它将提供类型安全验证,确认一些未知的json匹配你的typescript接口(你应该为JSON数据定义接口而不是类,它不能包含方法,所以一个接口就足以描述它)。

文件app/interfaces/contract.ts

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export interface IContract {
    id: string;
    name: string;
    spend: number;
}

运行此命令(在安装模块之后),它将生成一个新文件contract.validator.js

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
yarn typescript-json-validator --collection --aliasRefs --noExtraProps --strictNullChecks --coerceTypes app/interfaces/contract.ts

下面是一个使用示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import {validate} from "./interfaces/contract.validator";

const validateContract = validate('IContract');

const data: unknown = JSON.parse('{ "id": "42", "name": "Joe", "spend": "10000"}');
const contract = validateContract(data);
console.log(`Contract spend is ${contract.spend}: ${typeof contract.spend}` );

输出为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Contract spend is 10000: number

contract的类型在这里是IContract,并且所有类型都将匹配。你不必告诉typescript const contract: IContract,因为它会正确地推断出类型,但如果你愿意的话,你可以这样做。

如果JSON没有包含正确的字段,或者它们没有预期的类型,它将抛出一个错误。命令中的--coerceTypes选项允许进行一些转换,例如将字符串转换为数字。您还可以在界面的注释中包含其他约束,如正则表达式模式,请参阅文档。如果将多个接口放在一个文件中,--collection选项可以确保它们都可用,只需创建一个单独的验证器,传递每个接口的名称即可。

有一些恼人的限制,所以在界面中只使用简单的字符串和数字。例如,不要使用Date作为类型,因为它会验证字段是一个包含ISO格式日期的字符串,但它不会强制该类型,因此您仍然会得到一个字符串。但是,您可以使用注释来说明它是一个具有正确日期或日期-时间格式的字符串,然后使用经过验证的接口中的正确字段构造一个类。

票数 1
EN

Stack Overflow用户

发布于 2019-08-02 09:43:58

TypeScript类型在编译过程中会被移除--因为JavaScript ( TypeScript被转译为它)没有静态类型的概念。因此,在运行时“开箱即用”期间,无法确保值的类型正确。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57323811

复制
相关文章
TypeScript Number
TypeScript Number TypeScript 与 JavaScript 类似,支持 Number 对象。 Number 对象是原始数值的包装对象。 语法 var num = new Number(value); 注意: 如果一个参数值不能转换为一个数字将返回 NaN (非数字值)。 Number 对象属性 下表列出了 Number 对象支持的属性: 序号 属性 & 描述 1. MAX_VALUE 可表示的最大的数,MAX_VALUE 属性值接近于 1.79E+308。大于 MAX_VALUE
iOS程序应用
2023/05/05
5510
TypeScript Number
TypeScript 与 JavaScript 类似,支持 Number 对象。 Number 对象是原始数值的包装对象。 语法 var num = new Number(value); 注意: 如果一个参数值不能转换为一个数字将返回 NaN (非数字值)。 Number 对象属性 下表列出了 Number 对象支持的属性: 序号 属性 & 描述 1. MAX_VALUE可表示的最大的数,MAX_VALUE 属性值接近于 1.79E+308。大于 MAX_VALUE 的值代表 "Infinity"。 2.
陈不成i
2021/07/30
8340
为什么说 TypeScript 的火爆是必然?
TypeScript 这些年越来越火,可以说是前端工程师的必备技能了,各大框架都基于它实现。
神说要有光zxg
2022/04/12
6990
为什么说 TypeScript 的火爆是必然?
TypeScript 中的 Number 类型,Number 类型的特性、常见操作和注意事项
在 TypeScript 中,Number 类型用于表示数字。它可以包含整数和浮点数,用于进行数值计算和存储数值数据。本文将详细介绍 TypeScript 中的 Number 类型,包括 Number 类型的特性、常见操作和注意事项。
网络技术联盟站
2023/07/06
1.7K0
TypeScript系列 - 什么是TypeScript
看了很多关于TypeScript的文章,总体说来没有很好的,一个系统的学习TypeScript的资源。
Hongten
2019/02/25
1.1K0
TypeScript系列 - 什么是TypeScript
oracle number字段改为integer「建议收藏」
原文链接:http://www.fengyachao.com/archives/69
全栈程序员站长
2022/09/15
7340
为什么使用TypeScript
TypeScript是由微软开源的一种JavaScript超集语言,它不仅包含当前Javascript的特性,而且实现了esnext提案。TypeScript的宗旨是为JavaScript提供可靠的类型检查,避免出现意大利面条式的代码,在大型的项目中让源码更加可控。
conanma
2021/12/07
4650
为什么选择 TypeScript
相信经常关注前端技术的同学对 TypeScript 应该不陌生,或多或少看过一些关于 TypeScript 的文章。
陈皮皮
2020/06/28
1.7K0
为什么要用TypeScript
TypeScript的设计目的应该是解决JavaScript的“痛点”:弱类型和没有命名空间,导致很难模块化,不适合开发大型程序。另外它还提供了一些语法糖来帮助大家更方便地实践面向对象的编程。
用户7657330
2020/08/14
8600
为什么要用TypeScript
TypeScript是如何工作的
TypeScript 是一门基于 JavaScript 拓展的语言,它是 JavaScript 的超集,并且给 JavaScript 添加了静态类型检查系统。TypeScript 能让我们在开发时发现程序中类型定义不一致的地方,及时消除隐藏的风险,大大增强了代码的可读性以及可维护性。相信大家对于如何在项目中使用 TypeScript 已经轻车熟路,本文就来探讨简单探讨一下 TypeScript 是如何工作的,以及有哪些工具帮助它实现了这个目标。
ConardLi
2021/09/29
5.5K0
TypeScript是如何工作的
TypeScript String(字符串)
TypeScript String(字符串) String 对象用于处理文本(字符串)。 语法 var txt = new String("string"); 或者更简单方式: var txt = "string"; String 对象属性 下表列出了 String 对象支持的属性: 序号 属性 & 描述 实例 1. constructor 对创建该对象的函数的引用。 var str = new String( "This is string" ); console.log("str.constructor
iOS程序应用
2023/05/05
6040
为什么选择使用 TypeScript ?
相信经常关注前端技术的同学对 TypeScript 应该不陌生,或多或少看过一些关于 TypeScript 的文章。
陈皮皮
2020/07/10
2.4K0
如何自我介绍:我是字符串
字符串或串(String)是由数字、字母、下划线组成的一串字符。一般记为 s=“a1a2···an”(n>=0)。它是编程语言中表示文本的数据类型。在程序设计中,字符串(string)为符号或数值的一个连续序列,如符号串(一串字符)或二进制数字串(一串二进制数字)。
小Bob来啦
2020/12/16
6570
如何自我介绍:我是字符串
TypeScript: 为什么必须学
或者换一个问题,为什么在项目中,我们要选择使用typescript?也许你还不知道其中缘由,一起跟着我的思路捋一捋。
用户6901603
2020/07/25
1.3K0
TypeScript: 为什么必须学
为什么我觉得这次的chatGPT是真的智能AI
从上面可以看到,一个技术都是从萌芽期-膨胀期-低谷期-复苏期-成熟期,我们可以回顾一下所有经历过的技术,几乎都是沿着这个曲线进行发展的,最后到达成熟期之后为人所用,给人类的生活带来便利甚至改变人类的生活方式 ,
何处锦绣不灰堆
2023/03/07
7720
为什么我觉得这次的chatGPT是真的智能AI
TypeScript 是弱类型
以下这段代码不管是在 JavaScript 中还是在 TypeScript 中都是可以正常运行的,运行时数字 1 会被隐式类型转换为字符串 '1',加号 + 被识别为字符串拼接,所以打印出结果是字符串 '11'。
HoneyMoose
2021/11/16
6840
TypeScript 是弱类型
为什么说 Go 语言字符串是不可变的?
最近有读者留言说,平时在写代码的过程中,是会对字符串进行修改的,但网上都说 Go 语言字符串是不可变的,这是为什么呢?
AlwaysBeta
2023/06/02
3180
点击加载更多

相似问题

为什么在typescript中` `keyof any`的类型是` `string | number |symb`?

1131

为什么int是number.Number的子类?

12

为什么我收到错误信息"Invalid number“,因为UserID是NUMBER

262

TypeScript:索引签名参数必须是“string”或“number”。

21

为什么“< string>”>= <a number>是真的?

11
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文