数据类型
最新的ECMAScript标准定义了8种数据类型 7种原始类型:
- Boolean
- Null
- Undefined
- Number
- String
- Symbol
- BigInt 和Object类型;
原始类型:
// basic types
let isDone: boolean = false;
let age: number = 10;
let firstName: string = "mj";
let u: undefined = undefined;
let n: null = null;
// 未知类型
let noSure: any = 4;
noSure = "maybe a string";
noSure = true;
noSure.myName;
noSure.getName();
object类型:
// object类型
// Array
let arrOfNumbers: number[] = [1, 2, 3, 4];
arrOfNumbers.push(3);
// tuple
let user: [string, number] = ["mj", 22];
// function
function add(x: number, y: number): number {
return x + y;
}
let result = add(2, 3);
// 函数表达式
const add2 = (x: number, y: number): number => {
return x + y;
};
// type inference 类型推论
const add3 = add2;
接口Interfaces
1.对对象的shape进行描述:
interface Person {
readonly id: number;
name: string;
age?: number;
}
let mj: Person = {
id: 1,
name: "mj",
};
2.函数类型:
const sum = (x: number, y: number) => {
return x + y;
};
interface ISum {
(x: number, y: number): number;
}
const sum2: ISum = sum;
3.还能约束变化的属性名称,有可能有多个不确定的属性:
// 可索引的类型
interface RandomMap {
[propName: string]: string;
}
const test: RandomMap = {
a: "test1",
b: "test2",
};
// 类数组的结构
interface likeArray {
[propName: number]: string;
}
const arr: likeArray = ["1", "2", "3"];
4.定制化
// 类似于Reactde FunctionComponent
interface FunctionWithProps {
(x: number): number;
name: string;
}
const a: FunctionWithProps = (x: number) => {
return x;
};
a.name = "1";
类和接口
1.类的基本定义
// 类的基本定义
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
run() {
return `${this.name} is running`;
}
}
const dog = new Animal("pipi");
dog.run();
2.继承
// 继承
class cat extends Animal {
miao() {
return `${this.name} is miaomiao~`;
}
}
const xiongmao = new cat("xiongmao");
xiongmao.miao();
3.多态
//多态
class Mouse extends Animal {
constructor(name) {
super(name);
console.log(this.name);
}
run() {
return "shushu" + super.run();
}
}
const shushu = new Mouse("shushu");
ts如何增强类呢?
public公有,任何地方可以访问,默认都是public;private私有,不能在它声明之外的地方访问;protected子类中允许访问;
约束implements:
interface ClockInterface {
currentTime: number;
alert(): void;
}
interface GameInterface {
play(): void;
}
class Clock implements ClockInterface {
currentTime: number = 1;
alert(): void {}
}
class Cellpnone implements ClockInterface, GameInterface {
currentTime: number = 1;
alert(): void {}
play() {}
}
Clock implements一个interface只是约束了实例类型,对于静态类型需要创建另外一个interface来约束;
interface ClockInterface {
currentTime: number;
alert(): void;
}
// 静态类型
interface ClockStatic {
new (h: number, m: number): void;
time: number;
}
const Clock: ClockStatic = class Clock implements ClockInterface {
constructor(h: number, n: number) {}
static time;
currentTime: number = 1;
alert(): void {}
};
泛型Generics
函数没有类型推断; 如果有了泛型, 根据传参的类型,推断出返回数据的类型:
function swap<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]];
}
const res = swap(["string", 123]);
interface GithubResp {
name: string;
count: number;
}
interface CountryResp {
name: string;
area: number;
population: number;
}
function withAPI<T>(url: string): Promise<T> {
return fecth(url).then((resp) => resp.json());
}
withAPI<GithubResp>("github.user").then((resp) => {});
withAPI<CountryResp>("github.user").then((resp) => {});
泛型和接口举例
这里是仿写React的FunctionComponent;
interface FunctionComponent<P = {}> {
(props: P, context?: any): any;
}
interface TestProps {
title: string;
desc: string;
}
// 是将TestProps传递到函数的参数
const test: FunctionComponent<TestProps> = (props) => {
return `${props.title} ${props.desc}`;
};
深入泛型
1.交叉类型和联合类型
// 交叉类型
interface IName {
name: string;
}
type IPerson = IName & { age: number };
let person: IPerson = {
name: "hello",
age: 30,
};
// 联合类型
let numberOrString: number | string;
- 类型断言
// 类型断言
function getLength(input: number | string) {
const str = input as string;
if (str.length) {
return str.length;
} else {
const number = input as number;
return number.toString().length;
}
}
3.Partial用法;
// Partial用法
interface Person {
name: string;
age: number;
}
type PersonOptional = Partial<IPerson>;
// name和age属性都是可选的
let mj: PersonOptional = {};
type Partial<T> = {
[P in keyof T]?: T[P];
};
高级特性
- keyof
2.只能在Keys中选
interface CountryResp {
name: string;
area: number;
population: number;
}
type Keys = keyof CountryResp;
type NameType = CountryResp["name"];
// 只能在Keys中选
let key: Keys = "area";
- mapped keys
属性变为可选(类似于Partial的写法);
extends
// extends in generics
interface IwithLength {
length: number;
}
// 对函数进行约束,只能传入有length属性的变量;
function echoWithArr<T extends IwithLength>(arg: T): T {
console.log(arg.length);
return arg;
}
const arr = echoWithArr([1, 2, 3]);
const str = echoWithArr("111")
const obj = echoWithArr({length: 1})
// T的类型不是null或undefined就返回T
type NonType<T> = T extends null | undefined ? never : T;
//demo1是number
let demo1: NonType<number>;
//demo2是string
let demo2: NonType<string>;
定义文件
// 定义了jQuery的类型
declare var jQuery: (selector: string) => any;
可以直接安装第三方的声明文件npm包;
myFetch<string>("test", "DELETE", { name: "hello" }).then((data) => {
console.log(data);
});
myFetch.get<number>("test").then((data) => {});
type HTTPMethod = "GET" | "POST" | "PATCH" | "DELETE";
declare function myFetch<T = any>(
url: string,
method: HTTPMethod,
data?: any
): Promise<T>;
declare namespace myFetch {
const get: <T = any>(url: string) => Promise<T>;
const post: <T = any>(url: string) => Promise<T>;
}