稍等片刻,正在加载中...

Angular之TypeScript的入门(三)

介绍

TypeScriptJavaScript类型的超集,它可以编译成纯JavaScript

安装TypeScript

npm i -g typescript

检查是否安装成功:

tsc --version

如果输出版本号则说明安装成功了。

把ts编译成js

创建一个ts文件,名为demo1.ts,内容如下:

console.log('hello world');

下面的命令是把ts编译成js文件,命令如下:

tsc demo1.ts

上面的命令执行完后会在当前目录下生成一个demo1.js文件,内容如下:

console.log('hello world');

特点

变量类型

创建一个demo2.ts文件,内容如下:

// 声明一个变量,同时指定变量的类型为 number
let num: number;
// 由于 num 是一个 number 类型,在以后的使用过程中 num 的值只能是数字。
num = 1000;
// num = 'demo'; // 不能赋值数字
console.log(num);

let str1: string; // 定义string类型
// str1 = 111; //不能赋值数字,会报错
str1 = "i am string";
console.log(str1);

// 声明变量时并赋值,有点类似于`java`的写法。
let demo: boolean = true;
console.log(demo);


// 类型自动检测
let num1 = 111;
// num1 = '111'; // 不能赋值字符串

函数参数类型

语法:

function fn(参数: 类型, 参数: 类型)

创建一个demo3.ts文件,内容如下:

// 采用js的写法
function sum(a, b) {
    return a + b;
}

console.log(sum(111, 222)); // 333
// 下面的结果不是我们想要的
console.log(sum(111, '222'));  // 111222
console.log(sum("111", 222));  // 111222


// 采用ts的类型写法
function sum1(a: number, b: number) {
    return a + b;
}

console.log(sum1(111, 222)); //
// console.log(sum1(111, "222")); // 第二个参数 b 赋值为 字符串222,这里会提示报错

函数返回值类型

语法:

function fn(参数: 类型, 参数: 类型): 返回值的类型

创建一个demo4.ts,内容如下:

// 函数返回值只有一种返回值类型
function sum1(a: number, b: number): number{
    return a + b;
}

console.log(sum1(111, 222));

// 函数返回值有多种类型
function sum2(a: number, b: number): number | string{
    let c = a + b;
    if (c > 10){
        return 'demo';
    }else{
        return c
    }
}

相关类型

类型介绍

类型 描述
number 任意数字
string 任意字符串
boolean 布尔值truefalse
字面量 限制变量的值就是该字面量的值
any 任意类型
unknown 类型安全的any
void 没有值或者是underfind
never 不能是任何值
object 任意的js对象
array 任意的js数组
tuple 元素,TS新增类型,固定长度数组
enum 枚举,TS新增类型

number,string,boolean

// number类型
let num = 111;
let num1: number = 123;
let num2: number;
num2 = 3333;

// string类型
let str1 = 'demo';
let str2: string = 'demo1';
let str3: string;
str3 = 'demo2';

// boolean
let a = true;
let a2: boolean = false;
let a3: boolean;
a3 = true;

字面量

// 字面量
// 直接使用字面量进行类型的声明,有点类似于常量的用法
let b: 100;
// b = 101 // 会提示报错
b = 100;

// 另外的一种用法
let c: '男' | '女'; //
c = '男';
c = '女';
// c = 'aaa' // 会提示报错

// 用 | 来链接多个类型,叫做联合类型
let d: number | string | boolean;
d = 111;
d = 'demo';
d = true;

注意事项:

  • 如果一个变量有多种类型的话,可以使用|来进行多类型的联接。比如:let d: number | string。那么这个变量就可以在后面赋值多种类型了。

any

// any 不建议使用这种类型
// 显性any
let a4: any; // 类似于 let a4;
a4 = 11;
a4 = 'demo';
a4 = true;

// 隐性any
let a5;
a5 = 111;
a5 = 'demo';

// 如果一个变量的类型为`any`,那么它可以赋值给任意变量
let s1: string;
s1 = a4;

注意事项:

  • 声明变量时如果不指定类型,则ts解析器会自动判断变量的类型为any,这种叫做隐式的any。如果指定了any类型则为显式any
  • 如果一个变量设置成了any类型,就相当于对该变量关闭了ts的类型检测。
  • 如果一个变量的类型为any,那么它可以赋值给任意变量。

unknown

// nuknown 表示未知类型的值
let a6: unknown;
a6 = 10;
a6 = 'demo3';

let s2: string;
// s2 = a6; // 提示报错

//如果unknown的值真想要赋值给其他变量的话,可以做一下类型判断:
if(typeof a6 === 'string'){
    s2 = a6;
}

// 或者使用类型断言
s2 = a6 as string;
s2 = <string>a6;

注意事项:

  • unknown是一个类型安全的any类型。
  • unknown表示未知类型的值。如果你定义变量时不确定该变量的值的话可以使用它作为类型。
  • unknown类型的变量,不能直接赋值给其他变量。但是可以通过类型判断再赋值,或者是类型断言进行赋值。

void,never

voidnever主要用在函数的返回值类型中。

// void 一般不用于变量中,多数用于函数返回值中
function ss1(): void {
    console.log('void');
    // return 111;  // 提示报错,由于设置了该函数的返回值类型为 void

    // 下面的返回都可以
    // return null; // 可以返回 null
    // return undefined; // 也可以返回 undefined
    // return;
}


// never 表示永远不会返回值,null也不能返回,underfined也不能返回
function ss2(): never {
    console.log('never');
    // 下面的返回都会提示报错
    // return null;
    // return;
    // return undefined;

    // 下面的这种写法就不会提示报错了
    throw new Error("报错了");
}

注意事项:

  • 函数返回值类型为void时,可以返回nullundefined或者只写一个return也可以了。
  • 函数返回值类型为never时,永远都不会有返回值。

object

// object的表示
let a: object;
a = {};
a = function () {
    console.log('object')
};

// {} 用来指定对象可以包含哪些属性
// 语法:{属性名:属性值, 属性名: 属性值,...}


// 限制对象中的属性, 限制特定的属性
let a1: {name: string};
a1 = {name: 'demo'};


// 限制对象中的属性是可选的。
// 在属性名后面加 ? 表示该属性是可选的。
let a2: {name: string, age?: number};
a2 = {name: 'name11'};
a2 = {name: 'name22', age: 19};


//限制特定的属性,额外也可添加别的属性
// [demo: string]: any 表示可以任意类型的属性
let a3: {name: string, [demo: string]: any};  // demo是随机的一个名字
a3 = {name: 'name1', age: 19, sex: '男'};

let a4: {name: string, [dd: number]: number};
a4 = {name: 'ddd', 11: 11, 22: 33};


let a5: {[ee: string]: number, [num1: number]: number};
a5 = {age: 111, 11: 22, 22: 33, sex: 11};


// 对象函数
/**
 * 设置函数结构的类型声明
 * 语法:(形参: 类型, 形参: 类型,...)=>返回值类型
 */
let a6: (num1: number, num2: number) => number;
a6 = function (num1, num2) {
    return num1 + num2;
};

array

// array

// string[] 表示字符串数组。
let a1: string[];
// a1 = ['age', 111]; // 会提示报错,因为数组中元素存在 number 类型的元素
a1 = ['11', 'age', 'aaaa'];

let a2: number[];
// a2 = [1,2,3, 'aaa']; // 会提示报错,因为该数组中元素存在 string 类型的元素
a2 = [1, 22, 33];

// 另外一种表示方式
// 语法:Array<元素类型>
let a3: Array<number>;
// a3 = [1,2,33, 'aa']; // 会提示报错,该数组只能存放 number 类型的元素。
a3 = [11, 22, 333];

let a4: Array<string>;
a4 = ['aaa', 'aae'];

tuple

// tuple 元组就是固定长度的数组。
// 当我们数组中的长度是固定的时候就建议使用 tuple 这个类型

// 定义二个元素都是 string 类型的 tuple
let a1: [string, string];
// a1 = ['hee', 'demo', 'demo11']; // 只能是二个元素,因为该变量定义时就是二个元素。
a1 = ['aaa', 'bbb'];

let a2: [string, number];
// 会提示错误
// a2 = [11, 'demo'];  // 由于定义 tuple 时,第一个元素是 string 类型的,第二个才是 number 类型的。
// a2 = ['aaa', 'aaa']; // 元素类型不对,主要是第二个元素类型不对应造成提示错误。

// 正确的写法
a2 = ['ademo', 111];

enum

// enum 枚举
// 0 == male, 1 == female
enum Gender{
    male=0,
    female=1
}
let a3: {name: string, gender: Gender};
a3 = {name: '一切皆往事', gender: Gender.male};

if(a3.gender === Gender.male){
    console.log('这是male');
}else{
    console.log('这是female');
}

扩展用法

&的用法

// & 表示同时的意思
let a1: {name: string} & {age: number};
a1 = {name: 'demo', age: 111};

let a2: {name: string} & {age?:number};
a2 = {name: 'demo1'};
a2 = {name: 'demo2', age: 111};

类型别名

// 类型别名
type type1 = string;
let a3: type1; // 类似于 let a3: string; 的意思

// 用法
type type2 = 1 | "demo" | 22;
let a4: type2;
// 正确用法
a4 = 1;
a4 = 'demo';
a4 = 22;

// 提示错误,不是 1 | "demo" | 22 这三个值都会提示错误
// a4 = 222;

函数

js中的函数定义用法

// 函数声明
function sum(x, y) {
    return x + y;
}

// 函数表达式
let s1 = function (x, y) {
    return x + y;
};

typescript函数特点

  • typescipt会对函数的参数和返回值都会有约束。也是就是参数和返回值都会定义类型。

typescipt函数

函数表达式写法

// 函数定义
function sum1(x: number, y: number) : number {
    return x + y;
}

// 下面的写法实际上是将右侧匿名函数进行了类型的定义,对左边的 s2 变量没有实际的意义
let s2 = function (x: number, y: number): number {
    return x + y;
};

// 另一种写法
let s3: (x: number, y: number) => number = function (x: number, y: number) : number{
    return x + y;
};
  • typescript(x: number, y: number) => number=>是用于函数的定义,左边是参数的输入的类型,右边是返回值的输出的类型。

必选参数

function sum1(x: number, y: number) : number {
    return x + y;
}

可选参数

function sum2(x: number, y?: number) : number {
    if(y){
        return x + y;
    }else{
        return x
    }
}
注意事项
  • 可选参数必须放在必选参数的后面,而可选参数后面不能放必选参数。
  • 在必选参数后面加一个?号就代表该参数就会变为可选参数。

参数默认值

function sum3(x: number=11, y: number = 222) : number {
    return x + y;
}

function sum4(x: number=11, y?: number) : number {
    if(y){
        return x + y;
    }else{
        return x;
    }
}

未知参数

// 未知参数
// ES6的用法
function sss(...items) {
    console.log(items);
}

// typescipt的用法
// any[] 代表 任意的数组
function sum5(...items: any[]): string {
    return "123"
}

重载

// 重载
// 重载允许1个函数,接收不同参数或者类型的参数。
function sum6(x: number | string): number | string {
    return x;
}

接口

行为的抽象。比如:那个人比较漂亮。抽象出来:漂亮。

原js中的对象定义

// 原js的写法
let p = {
    name: '李四',
    age: 20,
    sex: '男',
};

属性必选与可选

// typescript的接口使用
interface  Person {
    name: string,
    age: number,
    sex: '男' | '女',
    money?: number, // 该属性为可选
}

// 定义一个人
let p1: Person = {
    name: '张三',
    age: 19,
    sex: '男',
    money: 1000
};


// 定义第二个人
let p2: Person = {
    name: '小东',
    age: 18,
    sex: '女'
};

可定义任意属性

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

let t1: Teacher = {
    name: '一切皆往事',
    money: 1000,
    school: '上海'
};

只读属性

// 只读属性
interface Cat {
    readonly name: string,
    color: string,
    age: number
}


let c1: Cat = {
    name: '经过',
    color: '黑色',
    age: 19
};

// c1.name = '修改name'; // 报错,该属性只能读

接口的特点

  • 约束对象。必须和接口一致属性。
  • 接口名称一般首字母大写。
  • 用接口定义的对象,属性不能多写。
  • 接口的属性要是定义为可选的话,需要在属性后面加上?号。

扩展操作

array与interface结合使用

// 采用接口表示数组中元素的类型
// 数组中的元素只能是number类型
interface NumberArray {
    [index: number]: number
}

// 正确用法
let arr1: NumberArray = [1, 2, 3, 4, 5];

// 错误用法
// let arr2: NumberArray = ['1', '2', 3, 4]; // 由于其中元素包含了字符串,所以会报错
posted @ 2021-10-23 19:28  一切皆往事  阅读(403)  评论(0)    收藏  举报