一.前言
谈到TypeScript,不得不熟悉Javascript是一种弱类型,动态类型检查的语言.
上面重点有两个关键字:弱类型,动态类型检查
什么是弱类型?
弱类型语言是指一个变量可以被赋值不同类型的数据.(与之相对的强类型则不行,强类型一旦指定了数据类型,如果不经过强制转换那么它永远是这个类型了)
什么是动态类型检查?
动态类型语言是在运行时才会进行类型检查.(与之相对的静态类型检查则是在编译时就进行类型检查,静态类型检查的时机更快.)
了解静态类型的好处与存在的问题
静态类型的好处:
1.尽早发现bug和错误;
2.提高代码的可读性(因为可以清晰告知需要什么数据类型);
3.减少了复杂代码的错误处理逻辑;(有了类型系统,那就不需要一个个判断错误的情况)
4.促进可靠的重构(修改函数其中一个参数,类型检查系统会提示其它地方一起修改)
5.增强IDE的功能(IDE是集成开发环境系统的意思)
静态类型的问题:
1.会增加代码量
2.需要花时间掌握类型
3.可能会降低开发效率
二.TypeScript简介
作者是微软公司,它是javascript的超集,它可以实现强类型,静态类型检查的一门语言.
简称TS,TS的作用总结一句话:它是用来做js类型检查的.
三.TypeScript使用
全局安装:
npm install -g typescript
安装好后会提供一个tsc命令给我们使用.(小提示:tsc命令需要管理员权限)
开始第一个代码:

编辑器马上回提示我们错误.
ts转换指定文件为js文件运行命令:
tsc ts文件名
运行完后它会自动生成对应的js文件
ts配置文件
生成配置文件命令
tsc --init
主要的配置有:
target:指将ts转换成哪个版本的js代码;
module:指将ts转换成js代码后,使用的模块化标准是什么;
outDir:指将ts转换成js代码后,js代码存放的位置;
rootDir:指哪个目录存放ts文件;
strict:是否将ts代码转换为严格模式的js代码;
执行配置命令后会自动生成新的文件

使用配置文件执行文件命令:
tsc -p ./tsconfig.json
四.TypeScript中的数据类型
数字类型number
除了支持十进制和十六进制字面量,TypeScript 还支持 es6中引入的二进制和八进制新的写法。

提示:
二进制数1101.01转化成十进制
1101.01(二进制数)=1*20+0*21+1*22+1*23 +0*2-1+1*2-2=1+0+4+8+0+0.25=13.25(十进制数)
十进制转二进制:

字符串类型string

布尔类型boolean
使用boolean来表示布尔类型

注意点:
用new Boolean(1)构造函数创建的对象不是布尔值,而是返回来的布尔对象;
var isDone = false;
var createdByNewBoolean = new Boolean(isDone);
console.log(createdByNewBoolean);//[Boolean: false]

或者我们不加关键字,直接调用Boolean()构造函数,返回的是boolean值;

数组类型number[]或Array

tuple元组(新增)
元组表示一个已知元素数量和类型的数组.

void空值类型(ts新增)
1.可以表示没有任何返回值的函数;
function alertName():void{
alert("xiaoming");
}
2.可以声明void类型的变量,但这样没什么用,它只能赋值为undefined
let unusable: void = undefined;
undefined类型和null类型(没变)

小结:与void的区别:undefined和null是所有类型的子类型,它可以赋值给其它类型的变量;而void类型不行.

//undefined类型和null类型
let u: undefined = undefined
let n: null = null
//undefined和null是所有类型的子类型,所以下面不会报错
let num: number = undefined
let num2:string=null
never类型(新增)
给永远没有返回值的函数定义为never类型

object类型
只要是引用类型,我们都可以使用object来定义
//object类型
let obj:object={};
let obj2:object=[];
指定对象类型{属性名:string,属性名:number}
指定了对象里的值是什么类型
let o:{name:string,age:number}={name:'小明',age:18}
枚举类型enum
比如我们有这样一个场景:0代表男,1代表女,2代表未知,这样数字名义不准确,于是有了枚举很方便来表示.
//枚举类型
enum Gender{
male=1,//男
female=0,//女
unknow=2//未知
}
let gender:Gender=Gender.male//这样就得到了1
//用对象也可以获取
let o2={
gender:Gender.male//这样就得到了1
}
类型推论
ts会在没有明确的指定类型的时候会推测出一个类型,这就是类型推论.

任意值类型
如果变量声明时没有指定类型,那么就是任意值类型.
如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查
注意:一开始不能赋值,如果赋值了就会进行类型推论

声明任意值类型后,写任意属性和方法不报错
可以认为:声明任意值后,对它的任意值操作,返回的内容类型都是任意值.
let anyThing: any = 'hello';
console.log(anyThing.myName);
console.log(anyThing.setName('Jerry'));//虽然没有属性和方法,但写时不报错
类型断言
有时候我们要比ts更早知道哪种类型,就可以使用类型断言
let len:number=(<string>str1).length;//指定了str1必须是字符串
五.ts中的类
类的例子
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");
如果你使用过 C#,你会对这种语法非常熟悉。 我们声明一个Greeter类。这个类有 3 个成员:一个叫做greeting的属性,一个构造函数和一个greet方法。
你会注意到,我们在引用任何一个类成员的时候都用了this。 它表示我们访问的是类的成员。
最后一行,我们使用new构造了Greeter类的一个实例。 它会调用之前定义的构造函数,创建一个Greeter类型的新对象,并执行构造函数初始化它。
类的继承
class Animal {
age: number
constructor(age: number) {
this.age = age
}
eat() {
console.log("动物都会吃东西");
}
}
class Dog extends Animal {
type: string
constructor(type: string, age: number) {
super(age)//如果使用了继承,就要使用super调用父类的方法
this.type = type
}
eat() {//父类也有同样方法,子类会覆盖掉,最终调用的是子类方法
console.log("泰迪吃东西");
}
}
var dog = new Dog('泰迪',18)
类成员的访问修饰符
什么是访问修饰符?
指的就是可以在类的成员前通过关键字来设置当前成员的访问权限.
权限有三种:
public:公开的,默认
private:私有的,只能在当前类中进行访问
protected:受保护的,只能在当前类或者子类中进行访问
public在公开修饰符里,下面三种情况color都可以访问
enum Color{
red="red",
yellow="yellow",
blue="blue"
}
class Car{
//不加访问修饰符,默认是公开的
color:string
constructor(){
this.color=Color.red
}
}
let byd=new Car()
// byd.color 可以访问
class Audi extends Car{
sayHi(){
console.log(this.color);//可以访问
}
}
let audi=new Audi()
// audi.color可以访问
private私有的:只能在当前类中使用
class Car {
constructor() {
this.run()//可以使用,加了private后只能在当前类中使用
}
//加了private,就只能在当前类中使用
private run() {
console.log("车跑");
}
}
let byd = new Car()
class Audi extends Car {
sayHi() {
this.run() //不可以访问
}
}
let audi = new Audi()
audi.run()//不可以使用
protected:只能在当前类或者子类中使用
在子类的实例中不能直接访问,但是可以借助子类的方法拿到.
class Car {
constructor() {
this.run()//可以使用,加了private后只能在当前类中使用
}
//加了private,就只能在当前类中使用
protected run() {
console.log("车跑");
}
}
let byd = new Car()
byd.run() //不在当前类,不可以访问
class Audi extends Car {
sayHi() {
this.run() //可以使用
}
}
let audi = new Audi()
audi.run()//不在当前子类,不可以使用
类的只读属性和类中构造函数参数简写
只读属性:只能访问不能修改
class Cat{
readonly name:string
constructor(){
this.name="加菲"
}
//说明:在ts中,类的属性必须要在声明的时候赋值,或者在构造函数中赋值(真实值或参数都可以),否则会报错
}
var cat =new Cat()
cat.name;
cat.name="新名"//只读属性,不可以
类中构造函数参数简写
/*
class Cat {
type: string
constructor(type: string) {
this.type = type
}
}
var cat = new Cat("加菲")
*/
//上面简写
class Cat {
constructor(public type: string) {
}
}
var cat = new Cat("加菲")
//也就是参数前面加一个public就等于写了type:string和this.type=type这两行代码
类的成员存取器
普通给类成员赋值这样就可以了
class People{
name:string=''
}
var p=new People()
p.name="我是很长的名字"
但是发现名字无法限制.
于是我们采用另一种方法:类成员存取器
它的作用是可以将类中接收到的属性值进行限制,具体如下:
/*
class People{
name:string=''
}
var p=new People()
p.name="我是很长的名字"
*/
//存取器的使用
class People{
_name:string=''
get name(){
return this._name
}
set name(value:string){
//这里可以做限制
if(value.length<2 || value.length>5){
throw new Error("名字不合法")
}
}
}
var p =new People()
p._name="我是很长的名字"
六.ts中的接口
接口基本使用方式
//参数规范
interface AjaxOptions{
url:string,
type:string,
data:object,
success(data:object):void
}
//ajax函数
function ajax(options:AjaxOptions){
}
//调用
ajax({
url:'http://www.baidu.com',
type:'get',
data:{},
success(data){
}
})
接口可选属性
给熟悉加了问号之后这个属性就可传可不传
//参数规范
interface AjaxOptions{
url:string,
type:string,
data?:object,
success(data:object):void
}
//ajax函数
function ajax(options:AjaxOptions){
}
//调用
ajax({
url:'http://www.baidu.com',
type:'get',
// data:{},//上面加了?这里就可以不用传
success(data){
}
})
接口只读属性
interface Point{
readonly x:number,
y:number
}
let poi:Point={
x:100,
y:200
}
// poi.x=110 错误,上面加了readonly就不可以重新赋值
接口的额外属性检查
interface Point{
readonly x:number,
y:number,
[propName:string]:any//接口额外属性,就是告知接口规范:我可能有别的其它属性和值,请忽略掉
}
let poi2:Point={
x:100,
y:200,
z:300 //额外的属性和值
}
函数类型的接口
interface SumInterFace{
(a:number,b:number):number
}
let sum:SumInterFace=function (a:number,b:number) {
return a+b
}
类类型的接口
与 C#或 Java 里接口的基本作用一样,TypeScript 也能够用它来明确的强制一个类去符合某种契约。
interface PersonInterFace {
name: string,
age: number,
eat(): void
}
class XiaoMing implements PersonInterFace {
name: string = "小明";
age: number = 18;
eat() {
}
}
接口继承接口
//接口继承接口(支持多继承)
interface TwoDPoint{
x:number,
y:number
}
interface ThreeDPoint {
z:number
}
interface FourDPoint extends ThreeDPoint,TwoDPoint{
time:Date
}
let poi3:FourDPoint={
x:100,
y:200,
z:300,
time:new Date()
}
接口继承类
//接口继承类
class Bird{
type:string="画眉鸟",
fly():void{
}
}
interface Fly extends Bird{
}
let f2:Fly={
type:"啄木鸟",
fly():void{
}
}
到这里就介绍完了,最后给出一点总结
TS是什么?
是微软开发的一款编程语言,是JavaScript超集!
TS能做什么?
TypeScript提供了类型系统
TS怎么用?
因为typescript是一个编程语言,它最终会被转换成javaScript代码运行,tsc就是用来进行转换的工具
-
安装 tsc
npm i typescript -g -
编写TS代码
-
利用tsc命令对文件进行编译 ts->js
TS的配置文件(建议先执行)
-
创建配置文件 .tsconfig.json
tsc --init -
常见配置属性
- target: 转换成的js代码的目标版本 ES ES3 ES5 ES6
- module: 转换成的js代码的模块化方式
- rootDir: ts代码存放的路径,要被转码的ts文件存放的路径
- outDir: 最终转换好的js文件的存储路径
- strict: 是否要转换成严格模式的代码
练习源码下载链接:
git@github.com:huanggengzhong/TypeScript.git
177

被折叠的 条评论
为什么被折叠?



