感受typescript定义变量和数据类型的神奇魔力

变量和数据类型

 你的Javascript能力到达瓶颈?那是因为你还不会typescript。掌握TS,让你的开发更加准确简洁。

今天的学习中,我们接着从TS的数据类型和变量入手,感受它们的奇妙魔力。

一. 变量声明方式

1.1. 声明变量的格式

我们已经强调过很多次,在TypeScript中定义变量需要指定 标识符 的类型。

所以完整的声明格式如下:

var/let/const标识符: 数据类型 = 赋值;

比如我们声明一个message,完整的写法如下:  

  • 注意:这里的string是小写的,和String是有区别的
  • string是TypeScript中定义的字符串类型,String是ECMAScript中定义的一个类
let message: string = "Hello World";

message =
"Hello TypeScript"; // 正确的做法
message =
20; // 错误的做法,因为message是一个string类型

1.2. 声明变量的关键字

在TypeScript定义变量(标识符)和ES6之后一致,可以使用var、let、const来定义:

var myname: string = "abc";
let myage: number = 20;
const myheight: number = 1.88;

但是,我们会发现使用var关键字会有一个警告:

var关键字警告

可见,在TypeScript中并不建议再使用var关键字了,主要原因和ES6升级后let和var的区别是一样的,var是没有块级作用域的,会引起很多的问题,这里不再展开探讨。

所以,在之后的开发中,我们定义变量主要使用let和const

1.3. 变量的类型推断

在开发中,有时候为了方便起见我们并不会在声明每一个变量时都写上对应的数据类型,我们更希望可以通过TypeScript本身的特性帮助我们推断出对应的变量类型:

let message = "Hello World";

上面的代码我们并没有指定类型,但是message实际上依然是一个字符串类型:

给message赋值一个number

这是因为在一个变量第一次赋值时,会根据后面的赋值内容的类型,来推断出变量的类型:

  • 上面的message就是因为后面赋值的是一个string类型,所以message虽然没有明确的说明,但是依然是一个string类型
let message = "Hello World"; // string类型
let age = 20; // number类型
let isFlag = true; // boolean类型

1.4. 声明name报错

我们在TypeScript的文件中声明一个name(很多其他的名字也会)时,会报错:

声明name报错信息

主要错误信息:

无法重新声明块范围变量“name”

我们前面明明(明明说管我什么事)没有声明name,但是却说我们重复声明了

  • 这次是因为我们的typescript 将 DOM typings 作为全局的运行环境;
  • 所以当我们声明 name时, 与 DOM 中的全局 name 属性出现了重名;

name的声明位置

如何解决这个问题呢?

  • 有两种方案:去掉DOM typings 的环境和声明模块

方式一:删除DOM typings的环境

但是这种办法对于我们来说并不合适,因为我们依然希望在DOM下编译我们的TypeScript代码

 

删除DOM typing

方式二:声明我们的ts文件为一个模块

既然与全局的变量出现重名,那我们将脚本封装到模块(module)中,因为模块有属于自己的作用域,就不会和全局的产生冲突:

  • 在Typescript 中,我们可以使用ES6的export来导出一个对象,并且该文件被视为module
let name = "coderwhy";

export {};

1.5. console.log报错

另外为了测试方便我们经常使用console.log来进行测试,但是使用时会报一个警告:

console.log警告

这个时候,我们可以配置

配置tslint

"no-console": false

二. JavaScript数据类型

2.1. number类型

数字类型是我们开发中经常使用的类型,TypeScript和JavaScript一样,不区分整数类型(int)和浮点型(double),统一为number类型。

// 1.数字类型基本定义
let num = 100;
num =
20;
num =
6.66;

如果你学习过ES6应该知道,ES6新增了二进制和八进制的表示方法,而TypeScript也是支持二进制、八进制、十六进制的表示:

// 2.其他进制表示
num =
100; // 十进制
num =
0b110; // 二进制
num =
0o555; // 八进制
num =
0xf23; // 十六进制

2.2. boolean类型

boolean类型只有两个取值:true和false,非常简单

// boolean类型的表示
let flag: boolean = true;
flag =
false;
flag =
20 > 30;

2.3. string类型

string类型是字符串类型,可以使用单引号或者双引号表示:

  • 注意:如果打开了TSLint,默认情况下推荐使用使用双引号
// string类型表示
let message: string = "Hello World";
message =
'Hello TypeScript';

同时也支持ES6的模板字符串来拼接变量和字符串:

const name = "why";
const age = 18;
const height = 1.88;

const info = `my name is ${name}, age is ${age}, height is ${height}`;
console.log(info);

2.4. array类型

数组类型的定义也非常简单,有两种方式:

  • 但是TSLint会推荐我们使用上面这种方式
const names1: string[] = ["why", "abc", "cba"];
const names2: Array<string> = ["why", "abc", "cba"];

2.5. object类型

object对象类型可以用于描述一个对象:

// object类型表示
const myinfo: object = {
  name:
"why",
  age:
20,
  height:
1.88,
};

但是上面的代码会报一个警告:

 

object定义后警告

这是因为TSLint建议我们所有的key按照字母进行排序,但是这个并不是特别有必要,我们还是可以关闭掉:

 

关闭TSLint字母排序

"object-literal-sort-keys": false

属性是不可以访问的

如果我们访问myinfo中的属性,会发现报错:

 

找不到name属性

这是因为TypeScript并不知道某一个object类型上面就有一个name的属性。

但是如果我们让它是类型推断的,就可以正常的访问:

  • 这是因为推导出来的类型,是如下的类型

myinfo的类型

还有一种方法是定义后面会学到的接口,TypeScript一个非常好用的特性就是接口interface,后续我们会进行非常详细的学习

2.6. symbol类型

在ES5中,如果我们是不可以在对象中添加相同的属性名称的,比如下面的做法:

const person = {
  identity:
"程序员",
  identity:
"老师",
}

通常我们的做法是定义两个不同的属性名字:比如identity1和identity2。

但是我们也可以通过symbol来定义相同的名称,因为Symbol函数返回的是不同的值:

const s1 = Symbol("identity");
const s2 = Symbol("identity");

const person = {
  [s1]:
"程序员",
  [s2]:
"老师",
};

这是Symbol的一个用法,更多其他用法大家可以自行学习,或者等到后续确实需要用到时,我们再详细讲解。

2.7. null和undefined

在JavaScript 中,undefined 和null 是两个基本数据类型。

在TypeScript中,它们各自的类型也是undefined和null,也就意味着它们既是实际的值,也是自己的类型:

const n: null = null;
const u: undefined = undefined;

三. TypeScript数据类型

 

TypeScript在原有的JavaScript基础上引入了很多好用的类型:enum枚举类型、tuple元组类型、any类型、void类型、never类型等

 

3.1. enum类型

3.1.1. 枚举的基本定义

枚举类型在很多语言都有的类型,比如C++、Java等等,并且也非常好用,所以TypeScript引入了enum类型,让我们开发更好的方便和安全。

枚举类型通常是定义一组数据:

enum Direction {
  EAST,
  WEST,
  NORTH,
  SOUTH,
}

const d1 = Direction.EAST;
const d2 = Direction.NORTH;

3.1.2. 枚举类型的值

枚举类型有自己的值,比如打印上面的d1和d2

打印d1和d2结果

默认情况下,枚举中的数据是从0开始的,我们可以改变它的初始化值,比如下面的代码:

enum Direction {
  EAST =
10,
  WEST,
  NORTH,
  SOUTH,
}

const d1 = Direction.EAST;
const d2 = Direction.NORTH;

console.log(d1); // 10
console.log(d2); // 12

也可以全部自己来指定:

enum Direction {
  EAST =
10,
  WEST =
20,
  NORTH =
30,
  SOUTH =
40,
}

const d1 = Direction.EAST;
const d2 = Direction.NORTH;

console.log(d1); // 10
console.log(d2); // 30

我们也可以通过对应的值去获取对应的数据名称:

console.log(Direction[10]); // EAST
console.log(Direction[30]); // NORTH

3.2. tuple类型

3.2.1. tuple的基本使用

tuple是元组类型,很多语言中也有这种数据类型,比如Python、Swift等。

const tInfo: [string, number, number] = ["why", 18, 1.88];
const item1 = tInfo[0]; // why, 并且知道类型是string类型
const item2 = tInfo[1]; // 18, 并且知道类型是number类型

3.2.1. tuple和数组类比

初学tuple会觉得它和数组非常相似

但是数组中通常会定义一组相同的数据,如果数据不同会造成类型的丢失:

  • 注意:这里我使用了一种联合类型,后面会讲到
const aInfo: Array<string|number> = ["why", 18, 1.88];
const itema = aInfo[0]; // why,但是并不知道itema是string类型还是number类型

3.3. any类型

在某些情况下,我们确实无法确定一个变量的类型,并且可能它会发生一些变化,这个时候我们可以使用any类型(类似于Dart语言中的dynamic类型)

let a: any = "why";
a =
123;
a =
true;

const aArray: any[] = ["why", 18, 1.88];

3.4. void类型

void类型通常用于函数没有返回值时来使用:

  • 首先我们需要说明的是,在TypeScript中函数也是有类型的

下面的函数,虽然我们没有指定它的类型,但是它会通过类型推导出来:

const sum = (num1: number, num2: number) => {
 
return num1 + num2;
};

// 相当于下面的写法
const sum: (num1: number, num2: number) =>number = (num1: number, num2: number) => {
 
return num1 + num2;
};
 

 

sum函数的类型

如果一个函数没有返回值,那么它的返回值类型就是void

  • 我们可以将null和undefined赋值给void类型,也就是函数可以返回null或者undefined
const sayHello: (name: string) =>void = (name: string) => {
 
console.log("hello " + name);
};

3.5. never类型

never类型表示一种从来不会存在的值的类型,有点绕,我们来这样理解:

  • 如果一个函数中是一个死循环,那么这个函数会返回东西吗?不会,那么写void类型或者其他类型作为返回值类型都不合适,我们就可以使用never类型。
  • 如果一个函数是抛出一个异常,那么这个函数是不是也没有返回值呢?这个时候我们也可以使用never类型。

死循环的函数抛出异常的函数

编程领域要走的路还很长,决不能满足于当前的现状而停滞不前。其实你静下心来思考一番,你会发现这其中还有很多未探索的奥秘等待的发现,前路也充满着趣味。如果你对此产生浓厚的兴趣,那就接着跟我一起在这个领域中散发光芒。

 

原文地址:https://www.cnblogs.com/waiwei/p/11909732.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我最大的一个关于TypeScript的问题是,它将原型的所有方法(无论访问修饰符)编译.例classExample{publicgetString():string{return"HelloWorld";}privategetNumber():number{return123;}}众所周知,访问修饰符仅在编译时检
我对React很新,我正在尝试理解子组件之间相互通信的简洁方法.在一个简单的组件中,我知道我可以使用props将数据传递给子节点,并让子节点的回调将数据传递回父组件.在稍微复杂的情况下,当我在父组件中有多个子组件时,子组件之间的通信会有点混乱.我不确定我应该为同级别的儿童组
我有一个非常简单的表单,我将用户电子邮件存储在组件的状态,并使用onChange函数更新状态.有一个奇怪的事情发生在我的onChange函数用函数更新状态时,我在键入时在控制台中得到两个错误.但是,如果我使用对象更新状态,则不会出现错误.我相信用函数更新是推荐的方法,所以我很想知道为
我发现接口非常有用,但由于内存问题我需要开始优化我的应用程序,我意识到我并不真正了解它们在内部如何工作.说我有interfaceFoo{bar:number}我用这种类型实例化一些变量:letx:Foo={bar:2}Q1:这会创建一个新对象吗?现在,假设我想改变bar的值.我这样做有两种
我得到了一个json响应并将其存储在mongodb中,但是我不需要的字段也进入了数据库,无论如何要剥离不道德的字段?interfaceTest{name:string};consttemp:Test=JSON.parse('{"name":"someName","age":20}')asTest;console.log(temp);输出:{name:'someName
我试图使用loadsh从以下数组中获取唯一类别,[{"listingId":"p106a904a-b8c6-4d2d-a364-0d21e3505010","section":"section1","category":"VIPPASS","type":"paper","availableTi
我有以下测试用例:it("shouldpassthetest",asyncfunction(done){awaitasyncFunction();true.should.eq(true);done();});运行它断言:Error:Resolutionmethodisoverspecified.SpecifyacallbackorreturnaPromise;n
我正在一个有角度的2cli项目中工作,我必须创建一个插件的定义,因为它不存在它的类型.这个插件取决于已经自己输入的主库,它可以工作.无论如何,我有两个文件主要的一个图书馆类型文件AexportclassAextendsB{constructor(...);methodX():void;}我需要为我的
我有三元操作的问题:leta=undefined?"Defined!":"DefinitelyUndefined",b=abc?"Defined!":"DefinitelyUndefined",//ReferenceErrorc=(abc!==undefined)?"Defined!":"DefinitelyUndefin
下面的代码片段是30秒的代码网站.这是一个初学者的例子,令人尴尬地让我难过.为什么这样:constcurrentURL=()=>window.location.href;什么时候可以这样做?constcurrentURL=window.location.href;解决方法:第一个将currentURL设置为一个求值为window.location.href的
我是TypeScript和AngularJS的新手,我正在尝试从我的API转换日期,例如:"8/22/2015"…到ISO日期.将日期正确反序列化为Date类型的TypeScript属性.但是,当我尝试以下命令时(在typescript中,this.dateDisplay的类型为string)this.dateDisplay=formats.dateTimeValue.toISOString
我的名为myEmployees的数组中有5个名字,但是当我运行代码时,它只打印出其中的3个.我相信这种情况正在发生,因为脚本中的for循环覆盖了它在HTML文档中编写的前一行.我怎样才能解决这个问题?YearlyBulletinBoardAnnouncements!CongratulationstoTaylor,youhavebeenheref
我看到有一种方法可以在摩纳哥编辑器中设置scrolltop.如何滚动到特定行而不是特定像素?解决方法:如在文档中:https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.icodeeditor.html滚动到顶部,在px中:editor.setScrollPosition({scrollTop:0});滚动到特定
在从同一个类继承的一个数组中收集各种不同的对象时,如何在TypeScript中设置一个优等的类,以便TypeScript不显示错误?我正在尝试这样:interfaceIVehicle{modelName:string}interfaceICarextendsIVehicle{numberOfDoors:number,isDropTop:boolean}inte
什么是TypescriptTypeScript是一种由微软开发的自由和开源的编程语言,它是JavaScript的一个超集,扩展了JavaScript的语法。作者是安德斯大爷,Delphi、C#之父(你大爷永远是你大爷)。把弱类型语言改成了强类型语言,拥有了静态类型安全检查,IDE智能提示和追踪,代码重构简单、可读性
0.系列文章1.使用Typescript重构axios(一)——写在最前面2.使用Typescript重构axios(二)——项目起手,跑通流程3.使用Typescript重构axios(三)——实现基础功能:处理get请求url参数4.使用Typescript重构axios(四)——实现基础功能:处理post请求参数5.使用Typescript重构axios(五
1.1Typescript介绍1.TypeScript是由微软开发的一款开源的编程语言,像后端java、C#这样的面向对象语言可以让js开发大型企业项目。2.TypeScript是Javascript的超级,遵循最新的ES6、Es5规范(相当于包含了es6、es5的语法)。TypeScript扩展了JavaScript的语法。3.最新的Vu
0.系列文章1.使用Typescript重构axios(一)——写在最前面2.使用Typescript重构axios(二)——项目起手,跑通流程3.使用Typescript重构axios(三)——实现基础功能:处理get请求url参数4.使用Typescript重构axios(四)——实现基础功能:处理post请求参数5.使用Typescript重构axios(
webpack.config.jsconstpath=require('path');constCopyWebpackPlugin=require('copy-webpack-plugin');constExtractTextPlugin=require('extract-text-webpack-plugin');const{CleanWebpackPlugin}=require('clean-webpac
我在这篇ECMAScriptpage上读到“class”是JavaScript的一部分.在这个关于TypeScript的页面上,我看到’class’也可以在Typescript中找到.我的问题是,开发未来JavaScript应用程序的正确方法是利用(a)JavaScript中的面向对象功能以及EMACScript7.0中可用的功能或(b)使用TypeScript