官方playground
官方也提供了一个在线开发 TypeScript 的云环境——Playground 英文版 中文版
基于它,我们无须在本地安装环境,只需要一个浏览器即可随时学习和编写 TypeScript,同时还可以方便地选择 TypeScript 版本、配置 tsconfig,并对 TypeScript 实时静态类型检测、转译输出 JavaScript 和在线执行。检查语法故障和检查逻辑故障。
一.基元类型
JavaScript 的类型分为两种:原始数据类型(Primitive data types)和对象类型(Object types)。
原始数据类型包括:布尔值、数值、字符串、null、undefined 以及 ES6 中的新类型 Symbol 和 ES10 中的新类型 BigInt。
1.基元类型(string,number,boolean)
const str:string = '';
const num:number = 0;
const bol:boolean = true;
2.数组(array)
- 「类型 + 方括号」表示
- 数组泛型(Array Generic) [
Array<elemType>] 表示 - 用接口表示
- any表示数组中允许出现任意类型
const arr:number[] = [1,2,3];
const arr2:Array<number> = [1,2,3];
interface NumberArray {
[index: number]: number;
}
let arr3: NumberArray = [1, 1, 2, 3, 5];
let list: any[] = ['xcatliu', 25, { website: 'http://xcatliu.com' }];
3.any(不希望某个特定值导致类型检查错误)
允许被赋值为任意类型
声明一个变量为任意值之后,对它的任何操作,返回的内容的类型都是任意值。
let myFavoriteNumber: any = 'seven';
myFavoriteNumber = 7;
4.变量上的类型注释
let str='';
str = 其他类型时报错
5.函数
在 JavaScript 中,有两种常见的定义函数的方式—— 函数声明 和 函数表达式
// 1.函数声明(Function Declaration)
function sum(x, y) {
return x + y;
}
// TS
function sum(x: number, y: number): number {
return x + y;
}
// 2.函数表达式(Function Expression)
let mySum = function (x, y) {
return x + y;
};
// TS
let mySum = function (x: number, y: number): number {
return x + y;
};
// TS优化版
// 在 TypeScript 的类型定义中,`=>` 用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型
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;
}
可选参数, 可选参数后面不允许再出现必需参数了
参数默认值, 没有可选参数必须接在必需参数后面」的限制了
function buildName(firstName: string = 'Tom', lastName: string) {
return firstName + ' ' + lastName;
}
buildName(undefined, 'Cat')
剩余参数
function push(array, ...items) {
items.forEach(function(item) {
array.push(item);
});
}
let a: any[] = [];
push(a, 1, 2, 3);
重载
重载允许一个函数接受不同数量或类型的参数时,作出不同的处理
function reverse(x: number | string): number | string | void {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}
参数类型注释(:string)/返回值类型注释(:void)
void 表示没有任何返回值的函数
类型推论: 根据输入值判断值是什么类型
function fun(name:string):void{
console.log(name)
}
// 声明一个 void 类型的变量没有什么用,因为你只能将它赋值为 `undefined` 和 `null`(只在 --strictNullChecks 未指定时):
let unusable: void = undefined;
6.对象类型
function fun2(obj: {x:string,y:string}):void{
console.log(obj.x, obj.y)
console.log(obj.x.toUpperCase())
}
fun2({x:1,y:2})
7.联合类型(两个或多个类型组成)
// 表示取值可以为多种类型中的一种
let myFavoriteNumber: string | number;
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;
myFavoriteNumber = true; //报错
// 访问此联合类型的所有类型里共有的属性或方法
function getLength(something: string | number): number {
return something.length; //报错,length不是number的方法
}
function getString(something: string | number): string {
return something.toString();
}
8.类型别名(首字母大写)
type Point = {
x: number;
y: number;
}
type ID = number | string;
type Str = string;
function fun(id: ID):void{
console.log(id)
}
type Large = Point & {
z: number;
}
const large: Large = {
x: 1,
y: 2,
z: 3
}
//type创建后不能更改
9.接口(首字母大写)
接口一般首字母大写。有的编程语言中会建议接口的名称加上 I 前缀。
赋值的时候,变量的形状必须和接口的形状保持一致, 不允许添加未定义的属性
interface Person {
name: string;
age: number;
}
let tom: Person = {
name: 'Tom',
age: 18
};
//可选属性
interface Person {
name: string;
age?: number;
}
let tom: Person = {
name: 'Tom'
};
// 任意属性
interface Person {
name: string;
age?: number;
[propName: string]: any;
}
// 如果任意属性定义为string, age的number会报错,所以应修改为联合类型
interface Person {
name: string;
age?: number;
[propName: string]: string | number;
}
// 只读属性
interface Person {
readonly id: number;
name: string;
age?: number;
[propName: string]: any;
}
interface Large extends Point: {
z: number;
}
const large: Large = {
x: 1,
y: 2,
z: 3
}
//向现有的类型添加字段
interface Lists: {
x: number;
}
interface Lists: {
y: number;
}
const list: Lists = {
x: 1,
y: 2,
}
10.类型断言
值 as 类型 或 <类型>值
interface Cat {
name: string;
run(): void;
}
interface Fish {
name: string;
swim(): void;
}
function swim(animal: Cat | Fish) {
(animal as Fish).swim();
// 一旦传入的参数是 `Cat` 类型的变量,由于 `Cat` 上没有 `swim` 方法,就会导致运行时错误了
}
### 将一个父类断言为更加具体的子类
class ApiError extends Error {
code: number = 0;
}
class HttpError extends Error {
statusCode: number = 200;
}
function isApiError(error: Error) {
if (error instanceof ApiError) {
return true;
}
return false;
}
// 返回某种类型的HTMLElement
const clas = document.getElementById('main_canvas') as HTMLCanvasElement
const clas = <HTMLCanvasElement>document.getElementById('main_canvas')
const x = ('hello' as any) as number
const x = ('hello' as unknow) as number
11.文字类型
// let声明后可修改, const 声明后不可修改
function compare(a:string, b:string): -1|0|1 {
return a === b ? 0: a > b ? 1: -1
}
const obj= {
x: 1
}
obj.x=2
obj.y =3 // Property 'y' does not exist on type '{ x: number; }'
const arr= [1,2,3,4]
arr.push(5)
12.null和undefined类型
// null不存在 undefined未初始化的值
let x:null = null
let y:undefined = undefined
function live(x?: number | null) {
console.log(x!.toFixed(2))
}
// 1. 属性或参数中使用 ?:表示该属性或参数为可选项
// 2. 属性或参数中使用 !:表示强制解析(告诉编译器,这里一定有值),常用于vue-decorator中的@Prop
// 3. 变量后使用 !:表示类型推断排除null、undefined
13.枚举
enum Point: {
Up = 1,
Down,
}
14.bigint和symbol
//bigint非常大的整数 symbol全局唯一引用
const num: bigint = BigInt(100)
15.内置对象
ECMAScript 标准提供的内置对象有:
Boolean、Error、Date、RegExp 等。
我们可以在 TypeScript 中将变量定义为这些类型:
let b: Boolean = new Boolean(1);
let e: Error = new Error('Error occurred');
let d: Date = new Date();
let r: RegExp = /[a-z]/;
DOM 和 BOM 提供的内置对象有:
Document、HTMLElement、Event、NodeList 等。
TypeScript 中会经常用到这些类型:
let body: HTMLElement = document.body;
let allDiv: NodeList = document.querySelectorAll('div');
document.addEventListener('click', function(e: MouseEvent) {
// Do something
});