一.为何学习TS
1.TypeScript 在社区的流行度越来越高,它非常适用于一些大型项目,也非常适用于一些基础库,极大地帮助我们提升了开发效率和体验。
2.TypeScript 可以编译出纯净、 简洁的 JavaScript 代码,并且可以运行在任何浏览器上、Node.js 环境中和任何支持 ECMAScript 3(或更高版本)的 JavaScript 引擎中。
3.强大的类型系统 允许 JavaScript 开发者在开发 JavaScript 应用程序时使用高效的开发工具和常用操作比如静态检查和代码重构。
4.TypeScript 提供最新的和不断发展的 JavaScript 特性,包括那些来自 2015 年的 ECMAScript 和未来的提案中的特性。
二.配置TS环境
1.安装好node
2.
# 安装
cnpm install typescript -g
# 查看版本号
tsc --version
tsc -v
3.node环境下执行Ts文件
// 1- 全局安装ts-node
cnpm install ts-node -g
// 2-可以通过命令ts-node来执行ts文件 。
ts-node 2.ts
三.静态类型
1.数字类型(number)
const num:number = 1;
2.字符串类型(string)
let str:string = "1"
3.布尔类型(boolean)
let bool:boolean = false;
4.数组类型(array)
//数组可以分为string与number类型
let arr1:string[] = ['1','2','3']
let arr2:num:number[] = [1,2,3]
//元组类型可以用于表示元素类型不同的数组,但前提是你要知道元素的数量与类型。 如下,我定义了第一个 元素为`string`类型,第二个元素为`number`类型的元组
let arr:[string,number] = ["abc",1]
//任意值类型(any) 当你数据类型不确定时,或者数组当中只知道部分元素的类型时,你就可以使用它了。
let arr:any[] = [1,2,"one",true,function(){},{}];
5.任意值类型(any)
let ones:any = 1;
ones = '3'
ones = true
let tow = 2
tow = '2'//报错
6.null与undefined
//`null`与`undefined`在学习`JS`时应该已经很熟悉了。关于`null`与`undefined`类型定义自身的这种行为,本身没有什么意义
let nu:null = null;
let nu2:null = 2;// 异常
let und:undefined = undefined
7.void类型
// void类型 `void`类型与`any`类型相反,它表示没有任何类型。声明一个`void`类型的变量是没有什么意义的,因为它的值只能是`undefined`和`null`.一半在声明函数时是否有返回值时使用
function fn():void{
// return undefined
}
//不写void就必须要写return并且返回的数据类型要与声明的时候一致
function fn():number{
return 1
}
function fn():string{
return '1'
}
8.枚举(enum)
//枚举 `enum` 类型是对 JavaScript 标准数据类型的一个补充,使用枚举类型可以`为一组数值赋予友好的名字`。 如果在程序中能灵活的使用`enum`,会让程序有更好的可读性。
// 1- 需要通过关键字enum来定义枚举
// 2- enum右侧即是枚举的名字
// 3- 枚举的命名规范:
// 3-1 枚举的名字首字母大写
// 3-2 枚举的名字以Enum结尾
// 3-3 枚举的成全要求全部大写,单词之间用_分割。
// 定义一个用于描述性别的枚举:NameEnum
// 成员的值默认从0依次递增。
enum NameEnum{
SEX,
AGE
}
console.log(NameEnum.SEX,NameEnum.AGE);// 输出0 1
// 可以指定成员值 也可以手动改写
enum NameEnum{
SEX = 100,
AGE
}
console.log(NameEnum.SEX,NameEnum.AGE);// 输出100 101
9.object
//object 表示非原始类型,也就是除 `number`,`string`,`boolean`之外的类型。
console.log(typeof {}); // object
console.log(typeof []); // object
console.log(typeof null); // object
const obj:{userName:string,age:number}={userName:"zhangsan",age:12};
10.联合类型(Union Types)
//联合类型 指定多个类型使用|进行分割,可以使用()将其包裹
let str:(string | number) = "abc";
str = 100;
str = true //报错
11.类型推断
//类型推断 TS会在没有明确的指定类型的时候推测出一个类型
let str = '1' //类型就为string
let num = 1 // 类型就为number
// 如果定义的变量未赋值,推断为any
let str;
str = 1;
str = "abc"
12.类型断言
//类型断言 通过*类型断言*这种方式可以告诉编译器 我知道是什么类型你不要操控了 交给我处理就可以了
const arr:number[] = [1,2,3,4];
//因为可能返回的时undefined 所以会报错 但我们知道这个肯定有返回值所有就断言有number类型的返回值
const num:number = arr.find(v=>v === 3) as number; //两种断言写法
const num2:number = <number>arr.find(v=>v === 2);
总结
// TypeScript是静态类型:在声明变量或常量时需要指定类型
let num:number = 1;
let str:string = "1"
let blo:boolean = true
//数组可以分为string与number类型
let arr1:string[] = ['1','2','3']
let arr2:num:number[] = [1,2,3]
//元组类型可以用于表示元素类型不同的数组,但前提是你要知道元素的数量与类型。 如下,我定义了第一个 元素为`string`类型,第二个元素为`number`类型的元组
let arr:[string,number] = ["abc",1]
//任意值类型(any) 当你数据类型不确定时,或者数组当中只知道部分元素的类型时,你就可以使用它了。
let arr:any[] = [1,2,"one",true,function(){},{}];
//null与undefined类型 无意义
let nu:null = null;
let und:undefined = undefined;
// void类型 `void`类型与`any`类型相反,它表示没有任何类型。声明一个`void`类型的变量是没有什么意义的,因为它的值只能是`undefined`和`null`.一半在声明函数时是否有返回值时使用
function fn():void{
// return undefined
}
//不写void就必须要写return并且返回的数据类型要与声明的时候一致
function fn():number{
return 1
}
function fn():string{
return '1'
}
//枚举 `enum` 类型是对 JavaScript 标准数据类型的一个补充,使用枚举类型可以`为一组数值赋予友好的名字`。 如果在程序中能灵活的使用`enum`,会让程序有更好的可读性。
// 1- 需要通过关键字enum来定义枚举
// 2- enum右侧即是枚举的名字
// 3- 枚举的命名规范:
// 3-1 枚举的名字首字母大写
// 3-2 枚举的名字以Enum结尾
// 3-3 枚举的成全要求全部大写,单词之间用_分割。
// 定义一个用于描述性别的枚举:NameEnum
// 成员的值默认从0依次递增。
enum NameEnum{
SEX,
AGE
}
console.log(NameEnum.SEX,NameEnum.AGE);// 输出0 1
// 可以指定成员值 也可以手动改写
enum NameEnum{
SEX = 100,
AGE
}
console.log(NameEnum.SEX,NameEnum.AGE);// 输出100 101
//object 表示非原始类型,也就是除 `number`,`string`,`boolean`之外的类型。
console.log(typeof {}); // object
console.log(typeof []); // object
console.log(typeof null); // object
const obj:{userName:string,age:number}={userName:"zhangsan",age:12};
//联合类型 指定多个类型使用|进行分割,可以使用()将其包裹
let str:(string | number) = "abc";
str = 100;
//类型推断 TS会在没有明确的指定类型的时候推测出一个类型
let str = '1' //类型就为string
let num = 1 // 类型就为number
// 如果定义的变量未赋值,推断为any
let str;
str = 1;
str = "abc"
//类型断言 通过*类型断言*这种方式可以告诉编译器 我知道是什么类型你不要操控了 交给我处理就可以了
const arr:number[] = [1,2,3,4];
//因为可能返回的时undefined 所以会报错 但我们知道这个肯定有返回值所有就断言有number类型的返回值
const num:number = arr.find(v=>v === 3) as number; //两种断言写法
const num2:number = <number>arr.find(v=>v === 2);
四.函数
1.参数类型注释 通过在参数后加冒号指定参数类型
// 声明函数1
const fn = function(a:number,str:string){
}
// 声明函数2
function fn2(a:number,str:string){
}
// 声明箭头函数
const fn3 = (num:number,str:string)=>{
}
2.函数返回值 形实参数量与类型需一致
// 要求返回值的类型为number
const fn = function(a:number,b:string):number{
return 1;
}
// 要求返回值的类型为string
const fn1 = function(a:number,b:string):string{
return 1;
}
// 不限制返回值的类型
const fn2 = function (a:number,b:string,c:number):any{
return "1"
}
// 不允许出现返回值
const fn3 = function():void{
return 1;// 异常
}
fn(1,'1')
fn2(1,1)//异常
fn2(1,'1')//异常
3.可选参数、默认参数、剩余参数
//可选参数
function fn(a: number, b?: string,c:number): number {
return 100;
}
fn(1, "abc");
fn(1);
//默认参数
// 参数b如果未传递,那么默认为0
function fn(a:number,b:number=0):number{
return a+b;
}
console.log(fn(1,2));// 3
console.log(fn(1));// 1
//使用....代表剩余
function fn(a:number,...lastNum:number[]):number{
console.log(lastNum);
return 100;
}
fn(1);
fn(1,2,3,4)
4.方法重载
函数重载是指同一个函数,根据传递的参数不同,会有不同的表现形式。注意在JS当中是不支持重载的。在TS中是提供了重载功能的,但是这个重载功能和C#或者java等语言的重载相比是不完整的。
function fn(name:string):string;
function fn(age:number):number;
function fn(message:any):any{
if(typeof message === "number"){
console.log("年龄",message);
}else if(typeof message == "string"){
console.log("用户名",message);
}
return "abc";
}
const str:number = fn(1);
五.接口
TypeScript 的核心原则之一是对值所具有的结构进行类型检查。我们使用接口(Interfaces)来定义对象的类型。
1.接口
// 接口是抽象表达的。
// 注意:接口的关键字--interface
// 接口的名字一般以I开头。
interface Iperson{
userName:string,
sex:string,
age:number
}
// 可以在对象名的右边加上:接口名字来使用接口
// 对象当中的属性类型一定要与接口指定的类型相同,否则有异常
// 对象当中不允许出现接口未定义的属性。
// 对象当中也不允许不写接口中定义的属性。
// (对象当中的属性一定要与接口一致)
const person:Iperson = {
userName:"张三",
sex:"男",
age:18,
}
// 对属性的类型是函数的进行约束
interface Iobj {
userName:string,
age:number,
run:(a:string,b:number)=>string
}
const obj:Iobj = {
userName:"张三",
age:12,
run(a:string,b:number){
return "abc"
}
}
console.log(obj.run("1",2))
2.可选属性与只读属性
// 可以通过?设置是否为必写项
interface Iperson{
userName:string,
sex:string,
age?:number
}
const person:Iperson = {
userName:"张三",
sex:"男",
age:18,
}
// 属性默认是可以进行读写的,在接口中如果增加readonly即可设置为只读属性
interface Iperson{
id:number,
readonly userName:string,
sex:string,
age?:number
}
const person:Iperson = {
id:100,
userName:"张三",
sex:"男",
age:18,
}
console.log(person.userName);// ok
const str:string = person.userName;// ok
person.userName = "李四";// 异常
3.使用断言
interface Iobj {
userName:string,
age:number
}
// 可以使用断言1
const obj = {} as Iobj;
obj.userName = "张三";
obj.age = 18;
// 可以使用断言2
const obj = {};
(<Iobj>obj).userName = "张三";
(<Iobj>obj).age = 18;
// 可以直接为对象增加接口
const obj:Iobj = {
userName:"李四",
age:17
}
obj.userName = "张三";
obj.age = 18;
4.接口可以继承接口
// Ione继承Iwo接口
interface Iwo {
sex:string
}
interface Ione extends Iwo {
id:number,
userName:string
}
const obj:Ione = {
id:100,
userName:"张三",
sex:"男"
}
5.函数类型
interface Ifn {
(userName:string,age:number):boolean
}
const run:Ifn = function(user:string,age:number):boolean{
console.log(user,age);
return true;
}
run("张三",18);
6.类实现接口
// 需要使用关键词implements
interface IBox{
run():string,
fn2():void
}
class Desk{
fn(){
console.log("fn");
}
}
class Box extends Desk implements IBox{
run(): string {
return "1"
}
fn2(): void {
}
fn3(){
console.log("fn3");
}
}
const box = new Box();
box.fn();
box.fn3();
7.接口继承接口
可以使用多个接口,多个接口用逗号进行分割。
interface ITwo{
fn5():number
}
interface IBox{
run():string,
fn2():void
}
class Desk{
fn(){
console.log("fn");
}
}
// 可以使用多个接口
class Box extends Desk implements IBox,ITwo{
run(): string {
return "1"
}
fn2(): void {
}
fn3(){
console.log("fn3");
}
fn5(): number {
return 12
}
}
const box = new Box();
box.fn();
box.fn3();