TypeScript入门教程一(通俗易通)

typescript现在已经慢慢变成前端工程师必学必会的技能了,它在开发大型应用的时候可以让代码更加可控,下面我是整理一些typeScript的基本的入门教程。

一.原始数据类型

JavaScript 的类型分为两种:原始数据类型(Primitive data types)和对象类型(Object types)。
原始数据类型包括:布尔值、数值、字符串、null、undefined 以及 ES6 中的新类型 Symbol。

1.布尔值(boolean)

布尔值是最基础的数据类型,在 TypeScript 中,使用 boolean 定义布尔值类型

let a: boolean = false;
let b: boolean = new Boolean(1);
let c: boolean =  Boolean(1);

typeScript环境下:
在这里插入图片描述
在这里插入图片描述
很显然,声明了boolean类型就必须是boolean类型的值, 上面错误也说了,‘boolean’ 是个原始类型,但是’Boolean’ 是个包装对象,所以会报错!

2.数值(number)

使用 number 定义数值类型:

let a: number = 6;
let b: number = 0xf00d;
// ES6 中的二进制表示法
let c: number = 0b1010;
// ES6 中的八进制表示法
let d: number = 0o744;
let e: number = NaN;
let f: number = Infinity;
console.log(a,b,c,d,e,f);

typeScript环境下:
在这里插入图片描述
上面是左边是typescript环境下的代码,右边是编译完之后的代码!其中 0b1010 和 0o744 是 ES6 中的二进制和八进制表示法,它们会被编译为十进制数字,执行结果如下图:
在这里插入图片描述



3.字符串(string)

使用 string 定义字符串类型:

let myName: string = 'Tom';
let myAge: number = 25;
console.log(`hello,my name is ${myName},my age is ${myAge}`)

typeScript环境下:
在这里插入图片描述
执行结果:
在这里插入图片描述


其中 用来定义 ES6 中的模板字符串,${expr} 用来在模板字符串中嵌入表达式。

4.空值(void)

JavaScript 没有空值(Void)的概念,在 TypeScript 中,可以用 void 表示没有任何返回值的函数:

function alertName(): void {
    alert('My name is Tom');
    return "My name is Tom"
}
alertName();

typeScript环境下:
在这里插入图片描述
在这里插入图片描述
已经定义了void类型,如果再return 就会报错,显示 type “my name is Tom” 不是指定的void的类型!
声明一个 void 类型的变量没有什么用,因为你只能将它赋值为 undefined 和 null!

function alertName(): void {
    alert('My name is Tom');
    return undefined || null
}
alertName();

typeScript环境下:
在这里插入图片描述

5.Null 和 Undefined

在 TypeScript 中,可以使用 null 和 undefined 来定义这两个原始数据类型,与 void 的区别是,undefined 和 null 是所有类型的子类型。也就是说 undefined 类型的变量,可以赋值给 number 类型的变量,而 void 类型的变量不能赋值给 number 类型的变量,看下代码:

let a: undefined = undefined;
let b: null = null;
let c: number = undefined;
let d: number = null;

let v:void
let e: number = v;

typeScript环境下:

在这里插入图片描述
在这里插入图片描述

二.任意值(Any)

如果是一个普通类型,在赋值过程中改变类型是不被允许的!

let a: string = 'string';
a = 7;

typeScript环境下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200905135413356.png#pic_center
报错提示 :7 不是指定的string类型!但如果是 any 类型,则允许被赋值为任意类型。

let a: any = 'string';
a = 7;

typeScript环境下:
在这里插入图片描述


甚至在任意值上访问任何属性都是允许的!可以认为,声明一个变量为任意值之后,对它的任何操作,返回的内容的类型都可以是任意值。

let anyThing: any = 'hello';
console.log(anyThing.split('-'));
console.log(anyThing.length);
console.log(anyThing.slice(1));

typeScript环境下:
在这里插入图片描述
看下面执行结果:
在这里插入图片描述
可以很随意写,因为他的返回值是没限制的,可以是任何类型,上面返回有Array,number,string类型!这里有一点需要注意的是:变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型(平时要规范写法)

let a;
//等价于
let a:any;
a = 'string';
a = 7;

typeScript环境下:
在这里插入图片描述
上面这样写是不会报错的!

三.类型推论(Type Inference)

顾名思义,如果没有明确的指定类型,那么 TypeScript 会依照类型推论的规则推断出一个类型。TypeScript 会在没有明确的指定类型的时候推测出一个类型,这就是类型推论。

let a = 'string';
a = 7;//会报错

上面代码我直接给个赋值为string类型,typescript会推断它是个string类型,所以在赋值为number会报错!看typeScript环境下:
在这里插入图片描述
在这里插入图片描述

四.联合类型(Union Types)

看意思也很好理解,联合嘛!取值可以为多种类型中的一种,联合类型使用 | 分隔每个类型。

let a: string | number = 7;
a = "string";
a = true;//会报错

看typeScript环境下:
在这里插入图片描述
在这里插入图片描述
当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法

function test(param: string | number): void{
    console.log(param.toString());
    console.log(param.slice(1));//会报错
    console.log(param.toFixed())//会报错
}
test("3");
test(3);

看typeScript环境下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
两者都有toString()方法,可以正常访问,但是number类型没有slice()方法,string类型没有toFixed()方法,所以都会报错!联合类型的变量在被赋值的时候,会根据类型推论的规则推断出一个类型,那么你只能用这个类型上的方法!否则会报错!

let param: string | number = 3;
console.log(param.toFixed());
console.log(param.slice());//会报错
param = "123";
console.log(param.split(''));
console.log(param.toFixed()); //会报错

看typeScript环境下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五.接口(Interfaces)

在面向对象语言中,接口是一个很重要的概念,它是对行为的抽象,而具体如何行动需要由(classes)去实现(implement)。TypeScript 中的接口是一个非常灵活的概念,除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述。

1.对象与接口

接口相当是一个约束,约束了对象的形状(属性)必须和接口(属性)保持 一致!

interface Person{
    name: string,
    age: number,
}

let zhangsan: Person ={
    name:'zhangsan',
    age: 18,
    sex:"man" //多了个属性会报错
} 

看typeScript环境下:
在这里插入图片描述
在这里插入图片描述
对象只能指定知道的属性,‘sex’ 在Person接口中不存在!再看看少属性会怎么样?

interface Person{
    name: string,
    age: number,
}

let zhangsan: Person ={
    name:'zhangsan',  //少了个属性
} 

看typeScript环境下:
在这里插入图片描述
在这里插入图片描述
它会很智能的告诉你,age属性缺少了!难道就不能多也不能少吗?(那要看你怎么定义接口了,下面会详细讲解),先引入一个可选属性,意思就是这个属性你可以选择要或者选择不要(那么不是可以少了,是的!),看下面例子

interface Person{
    name: string,
    age?: number,
}

let zhangsan: Person ={
    name:'zhangsan'
} 

看typeScript环境下:
在这里插入图片描述
没有报错,说明可选属性是可以不写的!那么有方法可以多写吗?有的,那么下面就要说下这个任意属性!看下面例子

interface Person{
    name: string,
    age?: number,
    [propName:string]:any
}

let zhangsan: Person ={
    name: 'zhangsan',
    sex:'man'
} 

使用 [propName: string] 定义了任意属性取 string 类型的值!,并且我定义所有的属性值是任意值,上面我也多写了个’sex’属性,看看typeScript环境下:
在这里插入图片描述
这里需要注意了, [propName: string]只是定义了所有的属性名是string类型,它的属性值是任意类型(如果不是any是string,那么age属性会报错),再看下面例子:

interface Person{
    name: string,
    age?: number,
    [propName:number]:string
}

let zhangsan: Person ={
    name: 'zhangsan',
    1:"新加的属性名必须是number,值必须是string,否则报错"
} 

看typeScript环境下:
在这里插入图片描述
上面改成[propName: number],那么就是number类型的属性名,它的属性值必须是string类型,有人会问,我想要这个属性只是可以读的,不能改的,能不能定义?答案是可以的,下面说下这个只读属性!

interface Person{
    readonly name: string,
    age?: number,
    [propName:number]:string
}

let zhangsan: Person ={
    name: 'zhangsan',
} 

zhangsan.name ='lisi' //会报错,可读属性不能修改

看typeScript环境下:
在这里插入图片描述
在这里插入图片描述
报错友好提示:不能指定’name’,因为它是一个常量(不变的)或者是一个可读的属性,这里zhangsan和Person接口一致,那么会先定义可读属性的值(不定义会报错)看下图:
在这里插入图片描述
在这里插入图片描述
所以只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候!

2.类与接口(implements)

这个是接口的另一个用途,对类的一部分行为进行抽象!实现(implements)是面向对象中的一个重要概念。一般来讲,一个类只能继承自另一个类,有时候不同类之间可以有一些共有的特性,这时候就可以把特性提取成接口(interfaces),用 implements 关键字来实现。这个特性大大提高了面向对象的灵活性,

1.类继实现接口:

比如动物有个共同的eat方法,狗,猫,都有eat方法,那么是不是可以把Animal当成接口,让狗,和猫各自都去实现eat方法!

 interface Animal{
     eat(food:string):void
 }

class Cat implements Animal{
	eat(food:string):void{
	console.log(`Cat eat ${food}`)
	}
}
class Dog implements Animal{
	eat(food:string):void{
	console.log(`Dog eat ${food}`)
	}
}
let cat = new Cat();
let dog = new Dog();
cat.eat('fish');
dog.eat('bone');

看下执行结果:
在这里插入图片描述

2.接口继承接口:

interface  Animal{
    eat(food:string):void;
}

interface Person extends Animal{
    thinking():void;
}

class Programmer implements Person {
    
    eat(food:string):void{
      console.log(`Programmer eat ${food}`);
    }
    thinking():void{
      console.log(`I'm thinking`);
    }
}

let programmer = new Programmer();
programmer.eat('meal');
programmer.thinking();

看下执行结果:
在这里插入图片描述

3.接口继承类:
当接口继承了一个类类型时,它会继承类的成员但不包括其实现。 就好像接口声明了所有类中存在的成员,但并没有提供具体实现一样。 接口同样会继承到类的private和protected成员。 这意味着当你创建了一个接口继承了一个拥有私有或受保护的成员的类时,这个接口类型只能被这个类或其子类所实现。看下面的例子:

class A {
    private name: string;
    protected age: number;
}

interface I extends  A {
    fn(): void;
}

class B extends A  implements I{
    fn():void{

    };
}

class D implements I{
    fn():void{

    };
}

typescript环境下执行:

在这里插入图片描述
为什么会报错呢?首先定义了一个A类,A类里面包含了私有属性name,和保护属性age,然后I接口继承A,所以I接口里面会有私有属性name,和保护属性age,那么必须要A的子类才能实现这个I接口,下面有个D类就不能实现I接口,因为D类里面没有私有属性name,和保护属性age,所以会报错!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值