介绍
TypeScript 基于 Javascript 基础之上的编程语言,是 JavaScript 的超集,或者叫扩展集。所谓超集就是在JavaScript 原有的基础上多了一些扩展特性,多出来的其实是一套更强大的类型系统,以及对 ECMAScript的新特性支持,它最终会编译成原始的 JavaScript。
安装
安装typescript
npm i typescript -g
安装 ts-node 测试编译运行 ts
npm i ts-node -g
编译
TS 本身没有运行环境,需要将 TS 编译为 JS 然后执行,JS 的运行环境就是浏览器和 Node。
TypeScript 的类型检查只是编译时的类型检查,而不是运行时的类型检查。一旦代码编译为 JavaScript,运行时就不再检查类型了。
ts的作用
- 编写一些公用方法和全局配置对象,用于提醒使用者别传错参数或者参数的值
- 编写组件的时候用于提示使用者有没有写错props
- 一些第三方库如果是ts编写,可以检测到使用者有没有调错方法,写错配置
总结
ts的最大意义就是避免写错、漏写,屏蔽掉一些低级错误。
1. typeScript 的特性有哪些?
- 类型批注
- 类型推断
- 类型擦除
- 接口
- 枚举
- mixin
- 泛型编程
- 名字空间
- 元组
类型批注
使用 :类型的形式来标注类型。
function add(a: number, b:number):number {
return a + b
}
add(1, 2)
基本类型批注: number bool string any
类型推断
// 初始化 类型->string
let str = 'Hello,world';
str = 1 // error
接口
描述对象类型 数据类型 number null string
interface User {
name: string
age: number
}
let user: User = {
name: '张三',
age: 18
}
区别
- TS是js的超集 扩展了js语法
- 只对ts代码进行编译
- .ts .tsx .dts
2. typeScript的数据类型有哪些?
- boolean
- number
- string
- array
- tuple 元组
- enum 枚举
- any
- null undefined
- void 类型
- never 类型 bottom lervel
- object 类型
boolean
let flag: boolean = true;
flag = false
number
let num: number = 1;
num = '2' // wrong
string
let str: string = 'hello';
let world = 'world';
let message = `hello,${world}`
any
let name: any = '1231';
array
let arr: string[] = ['1', '2', 3];
let number: number[] = [1, 2, 3];
tuple
let tupleArr: [number, string, boolean] = [1, '2', false];
enum
enum Size {
big,
middle,
small,
}
let a: Size = Size.big
null undefined
null undefined 所有类型的子类型
let num: number | undefined
num = 1
void
空类型 方法没有返回值
function get(): void {
console.log('no return value')
}
never
任何类型的子类型 代表不会出现的值
let a: never;
a = 1 // wrong
a = (() => {
throw new Error('wrong)
})()
object
对象类型 {}
let obj: Object;
obj = { name: '张三', age: 18 }
总结
- 基本类型 增加了 void any enum never
- 引用类型
3. 说说对Ts中高级类型的理解?有哪些?
高级类型
- 交叉类型
- 联合类型
- 类型别名
- 类型索引
- 类型约束
- 映射类型
- 条件类型
交叉类型
通过&将多个类型合并为一个类型 是一个并的操作
T & U
function extend<T, U>(first: T, second: U): T&U {
let result: <T&U> = {};
for(let key in first) {
result[key] = first[key]
}
for(let key in second) {
if (!result.hasOwnProperty(key)) {
result[key] = second[key]
}
}
return result;
}
联合类型
通过 | 实现,是一个或的意思
多个类型中的任意一个
T | U
number| string | boolean 只能有一个,不能共存
function formatCommandline(command: string[] | string) {
let line = '';
if(typeof command === 'string') {
line = command.trim();
} else {
line = command.join(' ').trim()
}
}
类型别名
通过type来定义 type SomeName = somexxx;
type some = boolean | string;
const a: some = true; // ok
const b: some = '张三'; //ok
const c: some = 1; //wrong
类型索引
keyof 类似 Object.keys
interface Button {
type: string
text: string
}
type ButtonKeys = keyof Buttonm // 'type' | 'text'
类型约束
通过 extends 来实现类型约束
type BaseType = string | number | boolean
// 对copy的参数进行类型约束
function copy<T extends BaseType>(arg: T): T {
return arg;
}
copy({}) // wrong
copy(1);
copy('zzz');
copy(true);
类型约束和类型索引一起使用
function getValue<T, K extends keyof T>(obj: T, key: K): T[k] {
return obj[key]
}
类型映射
通过in 实现
type Readonly<T> = {
readonly [P in keyof T]: T[P]
}
interface Obj {
a: string;
b: string
}
type ReadOnlyObj = Readonly<obj>;
/**
{
readonly a: string;
readonly b: string;
}
*/
条件类型
T extends U ? X : Y
3. ts中接口的理解?应用场景?
接口:方法特征的集合 interface
interface Person {
name: string;
age?: number;
readonly isMale: boolean;
say: (words: string) => string;
[propsName: string]: any // 对当前接口的拓展
}
// 继承接口 extends
interface Fater {
color: string
}
interface Mother {
height: number
}
interface Son extends Father, Mother {
name: string;
height: number;
}
应用场景
interface IUser {
name: string;
age: number
}
const getUserInfo = (user: IUser): string => {
return `name: ${user.name}, age: ${user.age}`
}
getUserInfo({name: '张三', age: '18'})
4. TS类
class OOP
类 是一种用户定义的引用类型
class Car {
engine: string;
constructor(engine: string) {
this.enghine = engine;
}
post(): void {
console.log(`引擎`, this.engine);
}
}
// 子类
class DrameCar extends Car {
post(): void {
super.post();
console.log(`dreameCar post`)
}
}
5. TS 修饰符
- pubilic: 可以自由访问类中定义的内容
- private: 只能在类的内部进行访问
- protect: 除了可以在该类内部访问,还可以在子类中访问
class Father {
private name: string;
constructor(name: string) {
this.name = name
}
}
const father = new Father('someone')
father.name // wrong
class Mother {
protected name: string;
constructor(name: string) {
this.name = name;
}
}
class Son extends Mother {
say() {
console.log(this.name)
}
}
6. TS 抽象类 & 使用技巧
抽象类能够作为其他派生类的基类去使用,抽象类一般不会直接被实例化
abstract
abstract class Animal {
abstract: song(); void;
move(): void {
console.log('move');
}
}
class Cat extends Animal {
song() {
console.log('miaomiao~')
}
}
const cat = new Cat();
cat.song();
cat.move();
补充
type 和 interface 区别
相同点:
1.type 和 interface 都可以描述对象和函数
// 定义对象
type Point= {
x: number;
y: number;
};
// 定义方法
type SetPoint = (x: number, y: number) => void;
// 定义对象
interface Point {
x: number;
y: number;
}
// 定义方法
interface SetPoint {
(x: number, y: number): void;
}
- 类型别名(type) 和 接口(interface)都支持扩展
type Animal = {
name: strng;
};
// 通过 & 拓展已定义的接口类型
type Bear = Animal & {
honey: boolean;
}
interface Animal {
name: string;
}
// 通过 extends 拓展
interface Bear extends Animal {
honey: boolean;
}
const bear: Bear = getBear();
bear.name
bear.honey
不同点:
- 同名的interface会自动合并,而type不会
interface User {
name: string;
}
interface User {
id: number;
}
let user: User = {
id: 666,
name: '张三'
}
user.id; // 666
user.name; // '张三'
type User = {
name: string;
};
// wrong 标识符"User"重复, ts(2300)
type User = {
id: number;
};
- type 可以为基本类型、联合类型或元组类型定义别名,而接口不行
type MyNumber = number; // 基本类型
type StringOrNumber = string | number; // 联合类型
type MyTuple = [number, string, number]; // 元组
类型别名(type) 和 接口(interface)的一些使用场景
使用类型别名的场景:
- 定义基本类型的别名时,使用 type
- 定义元组类型时,使用 type
- 定义函数类型时,使用 type
- 定义联合类型时,使用 type
- 定义映射类型时,使用 type
使用接口的场景:
- 需要利用接口自动合并特性的时候,使用 interface
- 定义对象类型且无需使用 type 的时候, 使用 interface