美文网首页
TypeScript基础语法篇

TypeScript基础语法篇

作者: 香喷喷啦啦啦66 | 来源:发表于2019-08-20 16:12 被阅读0次

TypeScript教程

参考,阮一峰:https://ts.xcatliu.com/basics/type-of-array

不解的地方:

ts函数的重载

ts函数的接口形式,看例子不太懂

typescript有两周类型的数据:原始数据和对象数据

原始数据类型包括:布尔值、数值、字符串、nullundefined 以及 ES6 中的新类型 Symbol

这里就较为特殊的布尔值,空值作简单介绍。

布尔值

布尔值是最基础的数据类型,在 TypeScript 中,使用 boolean 定义布尔值类型:
let isDone: boolean = false;
// 编译成功

注意,使用构造函数 Boolean 创造的对象不是布尔值:
let createdByNewBoolean: boolean = new Boolean(1);
// index.ts(1,5): error TS2322: Type 'Boolean' is not assignable to type 'boolean'

直接调用 Boolean 也可以返回一个 boolean 类型:
let createdByBoolean: boolean = Boolean(1);

空值

JavaScript 没有空值(Void)的概念,
//在 TypeScript 中,可以用 void 表示没有返回值的函数:
function alertName(): void {
    alert('My name is Tom');
}
声明一个 void 类型的变量没有什么用,因为你只能将它赋值为 undefined 和 null:
let unusable: void = undefined;

任意值

任意值(Any)用来表示允许赋值为任意类型。

什么是任意值类型

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

let myFavoriteNumber: string = 'seven';myFavoriteNumber = 7;
// index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'.   

但如果是 any 类型,则允许被赋值为任意类型。

let myFavoriteNumber: any = 'seven';myFavoriteNumber = 7;

任意值的属性和方法

在任意值上访问任何属性都是允许的:

let anyThing: any = 'hello';console.log(anyThing.myName);console.log(anyThing.myName.firstName);

也允许调用任何方法:

let anyThing: any = 'Tom';anyThing.setName('Jerry');anyThing.setName('Jerry').sayHello();anyThing.myName.setFirstName('Cat');

可以认为,声明一个变量为任意值之后,对它的任何操作,返回的内容的类型都是任意值

未声明类型的变量

变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型

let something;something = 'seven';something = 7;something.setName('Tom');

等价于

let something: any;something = 'seven';something = 7;something.setName('Tom');

什么是类型推论

以下代码虽然没有指定类型,但是会在编译的时候报错:

let myFavoriteNumber = 'seven';myFavoriteNumber = 7;
// index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'.

事实上,它等价于:

let myFavoriteNumber: string = 'seven';myFavoriteNumber = 7;
// index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'.

TypeScript 会在没有明确的指定类型的时候推测出一个类型,这就是类型推论。

联合类型

let myFavoriteNumber: string | number;myFavoriteNumber = 'seven';myFavoriteNumber = 7;
let myFavoriteNumber: string | number;myFavoriteNumber = true;
// index.ts(2,1): error TS2322: Type 'boolean' is not assignable to type 'string | number'.//   Type 'boolean' is not assignable to type 'number'.

联合类型使用 | 分隔每个类型。

这里的 let myFavoriteNumber: string | number 的含义是,允许 myFavoriteNumber 的类型是 string 或者 number,但是不能是其他类型。

访问联合类型的属性或方法

访问联合类型的属性,只能访问共有属性;或者等待数据类型确定后,访问对应的属性,看不懂看下面例子

当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法

function getLength(something: string | number): number {    return something.length;}
// index.ts(2,22): error TS2339: Property 'length' does not exist on type 'string | number'.//   Property 'length' does not exist on type 'number'.

上例中,length 不是 stringnumber 的共有属性,所以会报错。

访问 stringnumber 的共有属性是没问题的:

function getString(something: string | number): string {  
    return something.toString();
}

联合类型的变量在被赋值的时候,会根据类型推论的规则推断出一个类型:

let myFavoriteNumber: string | number;myFavoriteNumber = 'seven';
console.log(myFavoriteNumber.length); 
// 5myFavoriteNumber = 7;console.log(myFavoriteNumber.length); // 编译时报错
// index.ts(5,30): error TS2339: Property 'length' does not exist on type 'number'.

上例中,第二行的 myFavoriteNumber 被推断成了 string,访问它的 length 属性不会报错。

而第四行的 myFavoriteNumber 被推断成了 number,访问它的 length 属性时就报错了。

接口对象

简单的例子

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

let tom: Person = {
    name: 'Tom',
    age: 25
};

接口首字母大写

复杂例子

interface Person {
    readonly id: number;  //readonly修饰id,表示id只读,在第一次给对象Person赋值时候开始,id就不在允许赋值
    name: string;
    age?: number;  //  ?表示可选,表示age可以赋值也可以不
    [propName: string]: any;    // propName: string表示属性名是string类型,注意:接口中的所有属性的类型必须是:后面的子集
}

let tom: Person = {
    id: 89757,
    name: 'Tom',
    gender: 'male'
};

tom.id = 9527;  // 报错,因为对tom的id进行第二次赋值了

TypeScript中不同方式表示数组

类型+[]
let fibonacci: number[] = [1, 1, 2, 3, 5];

Array<泛型>
let fibonacci: Array<number> = [1, 1, 2, 3, 5];

接口形式表示数组
interface NumberArray {
    [index: number]: number;
}
let fibonacci: NumberArray = [1,1,2,3,]

any在数组中的应用

let arr1: any[] = [1,2,3,'2',{'i am jxy'}]

ts函数

声明函数

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

函数的两种表达方式

表达式

let mySum: (x:number, y:number) =>number =function(x:number, y:number):number{
    return x+y ;
}
// =>的左边()中的是输入类型,右边()中的是输出类型

接口形式(不解)

interface SearchFunc{
    (source:string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source:string, subString:string){
    return source.search(subString) !== -1;
}

ts函数的参数

可选参数

? 表示可选的参数:

function buildName(firstName: string, lastName?: string) {
    if (lastName) {
        return firstName + ' ' + lastName;
    } else {
        return firstName;
    }
}
let tomcat = buildName('Tom', 'Cat');
let tom = buildName('Tom');

需要注意的是,可选参数必须接在必需参数后面。换句话说,可选参数后面不允许再出现必须参数了

// **下面例子是错误实例,可选参数必须放在最后!!**
function buildName(firstName?: string, lastName: string) {
    if (firstName) {
        return firstName + ' ' + lastName;
    } else {
        return lastName;
    }
}
let tomcat = buildName('Tom', 'Cat');
let tom = buildName(undefined, 'Tom');

参数默认值

TypeScript 会将添加了默认值的参数识别为可选参数:

function buildName(firstName: string, lastName: string = 'Cat') {
    return firstName + ' ' + lastName;
}
let tomcat = buildName('Tom', 'Cat');
let tom = buildName('Tom');

此时就不受「可选参数必须接在必需参数后面」的限制了

剩余参数

ES6 中,可以使用 ...rest 的方式获取函数中的剩余参数(rest 参数)

在ts中...rest 可以理解为一个数组。所以我们可以用数组的类型来定义它:

function push(array: any[], ...items: any[]) {
    items.forEach(function(item) {
        array.push(item);
    });
}

let a = [];
push(a, 1, 2, 3);

重载

重载允许一个函数接受不同数量或类型的参数时,作出不同的处理。

比如,我们需要实现一个函数 reverse,输入数字 123 的时候,输出反转的数字 321,输入字符串 'hello' 的时候,输出反转的字符串 'olleh'

利用联合类型,我们可以这么实现:

function reverse(x: number | string): number | string {
    if (typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}

然而这样有一个缺点,就是不能够精确的表达,输入为数字的时候,输出也应该为数字,输入为字符串的时候,输出也应该为字符串。

这时,我们可以使用重载定义多个 reverse 的函数类型:

function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
    if (typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}

上例中,我们重复定义了多次函数 reverse,前几次都是函数定义,最后一次是函数实现。在编辑器的代码提示中,可以正确的看到前两个提示。

注意,TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。

相关文章

  • TypeScript基础语法篇

    TypeScript教程 参考,阮一峰:https://ts.xcatliu.com/basics/type-of...

  • TypeScript 基础语法

    1、void 与 undefined和 null 与 void的区别是,undefined 和 null是所有类...

  • TypeScript 基础语法

    TypeScript 程序由以下几个部分组成: 模块 函数 变量 语句和表达式 注释 使用以下 TypeScrip...

  • 《TypeScript》 - 基础语法

    TypeScript 程序由以下几个部分组成: 模块 函数 变量 语句和表达式 注释 tsc 常用编译参数如下表所...

  • TypeScript 基础语法

    TypeScript 的注释 首先我们来看一下注释,注释其实就是对代码的解释和说明,目的是让人们能够更加轻松地了解...

  • TypeScript 基础语法

    TypeScript 的注释 首先我们来看一下注释,注释其实就是对代码的解释和说明,目的是让人们能够更加轻松地了解...

  • TypeSctipt语法和类型基础

    TypeScript基础语法 TypeScript程序由以下部分组成: 模块 函数 变量 语句和表达式 注释 ts...

  • 学习 typescript 基础语法

    typescript 安装 npm install -g typescript 编译 tsc 文件名 TypeSc...

  • TypeScript 基础语法入门

    Vue3 基本全部使用 TypeScript 来进行重写,尽管你可能觉得要学的东西越来越多了,但是作为程序员,如果...

  • TypeScript 进阶语法

    本文接 TypeScript 基础语法入门[https://www.jianshu.com/p/8fe11ebb7...

网友评论

      本文标题:TypeScript基础语法篇

      本文链接:https://www.haomeiwen.com/subject/tkbpsctx.html