初探TypeScript 基础篇

973 阅读6分钟

前言

由于自己目前在学习typescript;想着边学习变做笔记,往后也可以翻出来看看,也分享出来给像我一样的初学者一起学习。望各位大佬指教。

简介

什么是TypeScript

TypeScript是Javascript的类型的超级,它可以编辑成Javascript,编译出来的代码可以运行在任何浏览器上,TypeScript编译工具可以运行在任何服务器和系统上,并且它是开源的。

为什么要选择TypeScript

1. TypeScript增加了代码的可读性和可维护性
    可以在编辑的夹断就发现大部分错误,比在运行程序的时候发现错误更加直观;
    增强了编辑器和IDE的功能,包括代码补全、接口提示等等
2. 拥有活跃的社区
    大部分第三方库都有提供TypeScript的类型定义文件

安装TypeScript

TypeScript 的命令行工具安装方法如下:

npm i -g typescript

以上命令会在全局环境下安装 tsc 命令,安装以后我们就可以在任何终端执行tsc命令了。我们可以简单的创建一个文件 hello.tsc 我们可以通过命令到当前文件所在目录,执行命令

tsc hello.tsc

编辑前代码 hello.tsc

function sayHello(person: string) {
    return `Hello,${person}`;
}
let user = 'Mark';
console.log(sayHello(user));

执行tsc hello.tsc后我们会看到同级目录下面会自动生成一个hello.js

function sayHello(person) {
    return `Hello,${person}`;
}
let user = 'Mark';
console.log(sayHello(user));

加入我们在sayHello方法中传入的是一个非string类型的参数 会发生什么呢

function sayHello(person: string) {
    return `Hello,${person}`;
}
let user = 10010;
console.log(sayHello(user));

编辑器中会提示错误,编译的时候也会出错:Argument of type 'number' is not assignable to parameter of type 'string'. 此时你会发现 TypeScript 编译的时候即使报错了,还是会生成编译结果,我们仍然可以使用这个编译之后的文件。

基础

上面简单的介绍了下TypeScript的安装及简单的hello实例,下面会介绍TypeScript 中的常用类型和一些基本概念,这样可以对TypeScript有个初步的了解;

原始数据类型

原始数据类型只要包括:boolean number string null undefined 以及es6中新的类型Symbol; 下面我们介绍:boolean number string null undefined在TypeScript中的使用

boolean

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

    let isSay: boolean = false; //编译通过
    // 我们在看下面一个 假如我们使用构造函数创建一个布尔值是否会编译用过呢????
    let createBoolean: boolean = new Boolean(8); // Type 'Boolean' is not assignable to type 'boolean'.
    // 所以使用构造函数 Boolean 创造的对象不是布尔值:

number

使用number定义数值类型:

    let age: number = 25 // 编译通过
    // 同样如果我们age变量赋值的为非number 编译就会报错

string

使用string定义数值类型:

    let name: string = 'mark' // 编译通过
    // 同样如果我们name变量赋值的为非string 编译就会报错

空值

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

    function sayHello(): void{
        console.log('我没有任何返回值');
    }

null & undefined

在 TypeScript 中,可以使用 null 和 undefined 来定义这两个原始数据类型:

    let m: undefined = undefined;
    let n: null = null;

注意: 因为undefined 和 null 是所有类型的子类型,所以null undefined可以赋值给其他类型

    let m: undefined = undefined;
    let age: number = m;
    // 编辑通过

任意值

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

什么是任意值类型

上面我们说到,如果是一个普通类型,在赋值的过程中改变类型是不允许的 但是如果是any类型,那么允许被赋值为任意类型。

    let age: number = 1; // 普通类型只能赋值number
    age = 'one'; // 报错
    let anyAge: any = 'one'; 
    anyAge = 1; // 编辑通过

类型推论

如果没有明确的指定类型,那么 TypeScript 会依照类型推论的规则推断出一个类型。 例如:

    let age = 1;
    age = 'one';
    //TypeScript 会在没有明确的指定类型的时候推测出一个类型 
    等价于
    let age: number = 1;
    age = 'one';

联合类型

联合类型?

联合类型表示取值可以为多种类型中的一种。

    let age: string | number;
    age = 1;
    age = 'one';
    // 以上编译是通过的;
    // 如果age是boolean呢
    age = false; // 编译报错

通过以上代码 可以得到一个结论:let age: string | number时,age的类型只能是string or number ,不能是其他类型。

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

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

    let age: string | number;
    age = 1;
    console.log( age.length ); // 编译时报错
    age = 'one';
    console.log( age.length ); // 3

对象的类型

对象的类型在 TypeScript 中我们使用接口来定义-- interfaces

interface Person {
    name: string;
    age: number;
}
let user: Person = {
    name: 'mark',
    age: 1,
}
// 假如我们
let user1: Person = {
    name: 'mark',
}
// or
let user2: Person = {
    name: 'mark',
    age: 1,
    work: 'web',
}
// 编辑报错

定义得变量比接口少了一些属性和多了一些属性都是不允许的,编译都会报错,所以在赋值的时候,变量的形状必须和接口保持一致。

假如我们想不要完全匹配一个形状 可以随意添加和减少怎么办呢?这个时候可以用到可选属性和任意属性 可选属性:该属性可以不存在 任意属性: 该属性可以是任意类型,但是要注意: 一旦定义了任意属性,那么确定属性和可选属性的类型必须是它的类型的子集。

insterface Person {
    name: string;
    age?: number;
    [propName: string]: any;
}
let user: Person = {
    name: 'mark',
    age: 1,
    work: 'web'
};
// 如果任意类型定义为string 那么 上面代码会报错。
insterface Person {
    name: string;
    age?: number;
    [propName: string]: string; //error TS2411: Property 'age' of type 'number' is not assignable to string index type 'string'
}

我们在平常工作中经常会希望有些字段只能在创建的时候被赋值,比如数据中的id; 在TypeScript中如何定义只读属性呢?

interface Person {
    readonly id: number;
    name: string;
    age?: number;
    [propName: string]: any;
}

let user: Person = {
    id: 1,
    name: 'mar;',
    work: 'web'
};
user.id = 2;
// 报错 Cannot assign to 'id' because it is a constant or a read-only property.

数组的类型

数组类型的表示方法:

类型+[] 表示法

let ages: number[] = [1,2,3,4,5];
let ages1: number[] = [1, 2, 3, '4']; // 报错
ages.push('2'); // 报错

数组泛型 Array<类型>

let ages: Array<number> = [1, 2, 3];

用接口表示数组

interface NumberArray {
    [index: number]: number;
}
let ages: NumberArray = [1, 1, 2, 3, 5];

函数的类型

一个函数有输入和输出,要在 TypeScript 中对其进行约束,需要把输入和输出都考虑到,其中函数声明的类型定义较简单:

function sum(x: number, y: number): number {
    return x + y;
}
// es6 => 用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型
let sum: (x: number, y: number) => number = function (x: number, y: number): number {
    return x + y;
};

同样 跟其他类型一样 输入多余的(或者少于要求的)参数,是不被允许的:

总结

以上是对TypeScript基础的一个学习。也是自己学习的一个笔记。奈何水平有限,望各位大佬指出问题,谢谢!