TypeScript
程序员文章站
2022-03-22 23:37:04
...
TypeScript
- TypeScript是JavaScript的一个超集,主要提供了类型系统和对ES6的支持,它由微软开发,开源于GitHub
- Typescript增加了代码的可读性和可维护性
TypeScript快速上手
-
可以在项目里或者全局安装TypeScript:npm install --save typescript 或npm install --g typescript,在命令行工具中tsc -v或者在package.json文件中查看安装是否完成
-
TypeScript使用已ts为后缀的文件,可以完全按照JavaScript的标准语法进行编写代码
-
在命令行工具中使用tsc --init生成tsconfig.json文件里面有配置选项
-
然后在VScode中点击终端运行任务,选择tsc:监视tsconfig.json,则可以实时编译检测ts
-
如果想在vscode查看ts所报的错为中文提示,输入typescript local,选择zh-CN中文(只是建议)
const hello = (name:string) =>{
console.log(`hello ${name}`);
};
hello('typescript');
TypeScript中的原始类型(Primitive Types)
//typescript原始类型
const a: string = "foobar";
const b: number = 100; //NaN、Infinity也可以
const c: boolean = true; //false
const d: null = null;
const e: void = undefined; //undefined类型值为void
const f: symbol = Symbol(); //因为ES5中没有Symbol,会报错,需要修改tsconfig.json中target配置为ES2015或者lib添加ES2015和DOM(添加DOM是为了解决ES2015中并没有console.log等BOM等操作)
console.log("hello");
TypeScript中的作用域问题
//不同文件中出现同名变量的问题,使用export导出,开发中都是这样操作
const a: number = 22;
export default a;
TypeScript中的Object类型(Object Types)
export {}; //确保跟其它示例没有冲突
//const foo:object = 123;//报错,object并不是指普通的对象
const foo: object = function () {};
// 变量所赋的值要跟前面保持一致,不能少不能多
//const obj: { foo: number; bar: string } = { foo: 123, bar: "string",more:122 };//more这里报错
const obj: { foo: number; bar: string } = { foo: 123, bar: "string" };
TypeScript中的Array类型(Array Types)
export {}; //确保跟其它示例没有冲突
//表示纯数字组成的数组
const arr1: Array<number> = [222, 33];
const arr2: number[] = [44, 555];
//---------------------------------
// 添加类型校验,数组元素须为number
function sum(...args: number[]) {
return args.reduce((prev, current) => prev + current, 0);
}
sum(1,2,3,'33');//强校验控制传入的参数,提示错误
sum(1,2,3,33);
TypeScript中的元组类型(Tuple Types)
export {};//确保跟其它示例没有冲突
//元组类型
// 只能存放两个对应类型的元素
const tuple: [number, string] = [18, "curry"];
// 使用数组下标访问
const age = tuple[0];
const name = tuple[1];
const [age1, name1] = tuple;
TypeScript中的枚举类型(Enum Types)
export {}; //确保跟其它示例没有冲突
//枚举类型
//使用enum关键字声明枚举类型
enum PostStatus {
Draft, //数字枚举不设置值,默认从0开始,下一个值如果没有设置值,则取上一个值加一
Unpublished,
Published = 2,
}
console.log("22");
const enum PostStatus1 {
Draft, //数字枚举不设置值,默认从0开始,下一个值如果没有设置值,则取上一个值加一
Unpublished,
Published = 2,
}
//字符串枚举需要设置值
enum PostStatusStr {
Draft = "aa",
Unpublished = "bb",
Published = "cc",
}
// 数字枚举可以通过索引访问,如果不想通过这个索引,则可以在enum前加const变为常量枚举
console.log(PostStatus[0]);
const post = {
title: "hello typescript",
content: "typescript is a typed super set of javascript",
status1: PostStatus1.Draft, //常量枚举,编译后的js会直接把PostStatus1.Draft的值写入
status: PostStatus.Draft, //这里的status值如果有限制的话,容易混入其他类型值,需要枚举器取值范围
};
TypeScript中的函数类型(Function Types)
export {}; //确保跟其它示例没有冲突
//函数类型
/**
* 对参数进行类型约束,如果有返回值也需要在括号后面对返回值进行约束
* 如果参数是可选参数(要放在最后一个参数),则在参数后面加上问号?标识
* 也可以对参数设置默认值
*/
function func1(a: string = "curry", b?: number): string {
return "func1";
}
//func1(11,33);//类型错误
func1("abc", 33);
func1("abc");
//-----------------------------------------------
//如果函数作为参数传入,则也需要对其进行类型设置
const func2: (a: number, b: number) => string = (
a: number,
b: number
): string => {
return "func2";
};
func2(1, 2);
TypeScript中的任意类型(Any Types)
export {}; //确保跟其它示例没有冲突
//任意类型
function stringify(value: any) {
return JSON.stringify(value);
}
stringify("string");
stringify(true);
stringify(100);
let foo: any = "string";
foo = 100;
foo = true;
//any类型是不安全的
TypeScript中的隐式类型推断(Type inference)
export {}; //确保跟其它示例没有冲突
// 隐式类型推断
let age = 10; //隐式推断为number
//age = '11';//提示错误
let foo; //这里隐式推断为any
foo = 100;
foo = "string";
TypeScript中的类型断言(Type Assertion)
export {}; //确保跟其它示例没有冲突
// 类型断言
// 假定这个nums来自一个明确的类型
const nums = [1, 33, 44, 55];
const res = nums.find((i) => i > 0);
//const num1 = res * res;//这里语法报错,不能确定res(number|undefined)的类型
//使用as关键字进行断言
const num1 = res as number;
const num2 = <number>res; //jsx下不能使用会冲突
TypeScript中的接口(Interface)
export {}; //确保跟其它示例没有冲突
//接口,使用interface定义
//约定对象成员中的类型
interface Post {
title: string;
content: string;
}
function print(post: Post) {
console.log(post.title);
console.log(post.content);
}
print({
title: "hello typescript",
content: "a javascript super set",
});
//设置对象的动态属性
interface Cache {
[prop: string]: string;
}
const cache: Cache = {};
cache.foo = "value1";
cache.bar = "value2";
TypeScript中的类(Class)
- 类的基本使用
export {}; //确保跟其它示例没有冲突
//类
class Person {
//访问修饰符private(私有属性,只能在内部访问),public(公有属性),protected(保护属性,只允许在类中和子类访问)
private name: string; //可以使用=设置初始值
public age: number; //typescript在类中的属性必须要有初始值或者在构造函数里初始化
// 可以设置只读属性,要么在属性声明时添加,要么在构造函数中添加
protected readonly gender: boolean;
//类中的属性需要声明类型,否则使用this会报错
// 构造函数也可以使用访问修饰符设置
constructor(name: string, age: number) {
this.name = name;
this.age = age;
this.gender = true;
}
say(msg: string): void {
console.log(msg, this.age, this.name);
}
}
class Student extends Person {
constructor(name: string, age: number) {
super(name, age);
console.log(this.gender); //子类能访问到该属性
}
}
const tom = new Person("tom", 12);
//console.log(tom.name);//在类外面无法访问
- 类与接口
export {}; //确保跟其它示例没有冲突
// 类中使用接口,配合使用implements进行类型限制
interface Eat {
eat(food: string): void;
}
interface Run {
run(distance: number): void;
}
class Person implements Eat, Run {
eat(food: string): void {
console.log(`优雅的进餐:${food}`);
}
run(distance: number): void {
console.log(`直立行走:${distance}`);
}
}
class Animal implements Eat, Run {
eat(food: string): void {
console.log(`呼噜呼噜的吃:${food}`);
}
run(distance: number): void {
console.log(`爬行:${distance}`);
}
}
- 抽象类
export {}; //确保跟其它示例没有冲突
//抽象类
/**
* 抽象类使用abstract关键字标识,一旦类使用了abstract关键字标识,则该类只能被继承,无法创建实例对象
*/
abstract class Animal {
eat(food: string): void {
console.log(`呼噜呼噜的吃:${food}`);
}
// 抽象方法,一旦父类定义,子类中就必须实现该方法
abstract run(distance: number): void;
}
class Dog extends Animal {
run(distance: number): void {
console.log(`爬行:${distance}`);
}
}
const d = new Dog();
d.eat("fff");
d.run(2222);
TypeScript中的泛型(Generics)
export {}; //确保跟其它示例没有冲突
//泛型
/**
*把定义时不明确的类型作为参数,在使用的时候传入类型值当作这个参数实现复用
*/
function createNumArray(length: number, value: number): number[] {
const arr = Array<number>(length).fill(value);
return arr;
}
function createStrArray(length: number, value: string): string[] {
const arr = Array<string>(length).fill(value);
return arr;
}
function createArray<T>(length: number, value: T): T[] {
const arr = Array<T>(length).fill(value);
return arr;
}
const res = createNumArray(3, 100);
const res1 = createStrArray(4, "acb");
const res2 = createArray<string>(3, "cjr");
const res3 = createArray<number>(3, 444);
TypeScript中的类型声明
export {}; //确保跟其它示例没有冲突
//类型声明
/**
* 使用declare关键字标识
*/
import { camelCase } from "lodash";
//原始的lodash方法中没有类型声明
declare function camelCase(input: string): string;
const res = camelCase("hello typescript");
"acb");
const res2 = createArray<string>(3, "cjr");
const res3 = createArray<number>(3, 444);
TypeScript中的类型声明
export {}; //确保跟其它示例没有冲突
//类型声明
/**
* 使用declare关键字标识
*/
import { camelCase } from "lodash";
//原始的lodash方法中没有类型声明
declare function camelCase(input: string): string;
const res = camelCase("hello typescript");