ts
typescript是拥有类型的javaScript超集, 它可以编译成普通\干净\完整的js代码 ,始于js,终于js,
安装
npm install -g typescript
tsc 文件名 //将ts文件编译成为js文件。
vsCode自动编译ts
// 1.新建个index.ts文件
// 2.终端执行 tsc --init 会在自动生成tsconfig.json文件 修改这个文件outDir为 "outDir": "./js",
// 3.Vs Code 打开终端 ->运行任务 -> typescript ->"tsc: 监视 - tsconfig.json (ts"
命令行启动
npm install node-ts -g // 安装node-ts
node-ts '文件名' // 使用方法
数据类型
number
包含NaN ,二进制,十进制,八进制等数字
let num: number = 123;
num = 100;```
booleab
布尔值 只有 true 、false 两个值
let flag: boolean = true;
flag = false;
flag = 1 > 0;
string
let msg: string = "hello world";
null和undefined
js中null和undefined是两个基本数据类型
在ts中 null和undefined他们是类型 也是值
var n = null;
var u = undefined;
n = null;
n = undefined;
symbol
表示唯一值
// @ts-ignore
let sym1: symbol = Symbol("name");
// @ts-ignore
let sym2: symbol = Symbol("name");
const obj = {
[sym1]: "hello world",
[sym2]: "你好世界",
}
数组
在数组中最好放相同数据类型的内容
let arr: number[] = [] // 写法1
let arr1: Array<string> = [] // 写法二 jsx中尽量不要使用这个方式
object
const obj = {
name: "你好世界",
age: 18
}
any
any类型表示任意类型
let msg: any = "1234";
msg = 123;
msg = true;
msg = [];
msg = null;
unknow
unknown类型 只能赋值给any和unknown类型的变量
let flag:boolean = true;
let res: unknown='你好世界';
// let msg: any = res //ok
let msg: unknown = res // ok
flag=res // 报错 不能将类型“unknown”分配给类型“boolean”
void
当前方法没有返回值
never
通常用来声明永远不会正常返回的函数的返回值类型
function fn(): never {
throw new Error('never类型')
}
元组 Tuple
已知元素数量和类型的数组,各元素的类型不必相同
let tup: [number, string] = [1, '1']
// 如果不确定可以使用? 只能放在最后以为使用
let tup: [number, string?] = [1]
enum
enum 声明的都是常量
// 数字枚举
// enum Color {Red, Green, Blue} Red:0 Green:1 Blue:2
// enum Color {Red, Green=100, Blue} Red:0 Green:100 Blue:101
enum Color { Red, Green = 100, Blue }
let c: Color = Color.Blue // 101
// 字符串枚举
// 在字符串枚举里,每个成员都必须用字符串字面量进行初始化。
enum Direction { Up = "UP", Down = "DOWN", Left = "LEFT", Right = "RIGHT", }
let up:Direction=Direction.Up
console.log(up);
// 混合枚举
//只有第一位可以不用定义
enum blend{
empty,
num=1,
str='1'
}
补充数据类型
联合类型
type union=string | number
let num:union='123'
let num1:union=123
可选类型 ?
类型别名
type newNumber=number
类型断言
ts无法获取具体的类型信息(HTMLElement),但是这些(HTMLImageElement)信息有又独特的属性和方法,此时就需要告诉ts当前的这个数据类型到底是那种
// TS只允许类型断言转换为 更具体 或者 不太具体(any/unKnown) 的类型版本. 这种情况会导致ts类型混乱
let num = <number>1 //<>写法
let str = '1' as string // as写法
//HTMLElement as HTMLImageElement
let img = document.getElementById("img") as HTMLImageElement
let str: string = "你好世界";
let num: number = str as unknown as number
?? == || , !!==Boolean()
字面量类型
//ts中字面量类型
let str: "你好世界" = "你好世界"
类型缩小==>类型保护
//typeof
//instanceof
//常见的比较 (== === != !==) switch
//in in 用于确定对象是否具有带名称的属性
//is is类型谓词 判断一个变量是否为该类型
// keyof 返回接口中的所有key值 并生成联合类型
函数
let fn:Function=function(){} //声明函数第一种方式
let fn1:()=>void=()=>{} //声明函数第二种方式
//函数能够通过传递参数的类型自动推导返回值的类型
//ts中使用 arguments 会报错 可以使用...展开运算符获取
// 当函数在外部时需要在函数中定义一个形参 this ,函数体内才能正常使用this
//函数重载
//通过函数签名的形式来实现函数重载
function sum(a1:number, a2:number): number;
function sum(a1:string, a2:string): string;
function sum(a1: any, a2: any){
return a1+a2
}
//在调用函数的时候,它会根据我们传入的参数类型,来对函数签名一个一个对比,哪怕数据类型是any只要不符合任意一个重载函数签名,那么都是不能使用的来决定执行函数时,到底执行哪一个函数签名
sum(1,2);//3
sum("1","2");//"12"
泛型
定义一个方法或者接口的时候,不确定用户传递什么类型的参数回来 那么也就不能确定返回值,需要使用者来进行传递
// 传入什么类型返回什么类型
function fn<t, f>(a: t, b: f): void {
}
fn<string, number>('1', 2) //传值的时候固定参数类型 或者不固定参数类型 fn('1', 2)
interface Lengthwise {
length: number;
}
// 泛型约束
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length); // 5
return arg;
}
loggingIdentity('11') // 此时函数默认推导出字面量类型:11
//约定俗成的开发过程中一些常见名称
//T: type的缩写, 类型
//K/V: key和value的缩写, 键值对
//E: element的缩写, 元素
//O: object的缩写, 对象
function isNumber(x: any): x is number {
return typeof x === "number";
}
忽略ts下一行报错
// @ts-ignore
接口
interface
interface 可以重复声明 默认合并以前的
type重复声明会报错,默认替换所有不难为window声明类型断言,interface就可以
// 声明一个 interface 接口
interface InterfaceA {
readonly num: number, // 只读属性
str?: string // 可选类型
}
// 索引类型
interface Indexes {
[name: number]: string
}
let obj: Indexes = {
1: '1',
2: '2',
3: '3',
}
interface InterfaceB {
}
interface InterfaceC {
}
// 接口继承
interface InterfaceD extends InterfaceB, InterfaceC {
}
// 接口泛型
interface UserInfo<T> {
id: T;
age: number;
}
const userInfo: UserInfo<number> = {
id: 123,
age: 23,
}
// interface 重复声明具有合并一起声明 的类型
type
// type泛型
type UserInfo<T> = { //
id: T,
age: number
}
type Username = { //
name: number
}
//type的交叉类型 类似于 Interface 的 extends 继承
const userInfo: UserInfo<string> & Username = {
id: '123',
age: 18,
name:'李四'
}
type 与 interface
//我们发现interface和type都可以用来定义类型, 那么在开发过程中,到底应该选择哪个
//1. 如果定义的是对象类型,那么通常推荐使用interface
//2. 如果定义的是非对象 function Direction 推荐使用type
//interface和type之间有什么异同
//1.interface可以重复声明 type不能重复声明
//2.type定义的别名, 别名是不能重复
声明一个类型判断的数组
interface InterfaceA {
num: number, // 必须有
str?: string // 可选可不选
}
let arr:InterfaceA[]=[]
class 类
- public:默认值
- private : 只能在当前类中使用访问这个变量,实例和子类都不能获取和使用
- protected:可以在类和子类中使用修改,实例上不能
- 使用 static 开头的属性(方法)就是静态属性(方法),也称为类属性。只能在类中使用也是可以被继承的
- 使用静态属性无需创建实例,可直接通过类来使用
abstract class Abs { // abstract 修饰的是抽象类 不能被实例
}
class Person {
static hobby: string = '学习' // static 静态属性只能通过类来获取
readonly name: string //只读
private sex: string // private 修饰符私有属性 只能让元素在当前类中访问
protected age: number // protected 修饰符 类似 private 修饰 符 只是可以被 子类继承并且访问
constructor(name: string, age: number, sex: string) {
this.name = name
this.sex = sex
this.age = age
}
getPrivate() {
console.log(this.sex); // ok
console.log(Person.hobby); // 可以获取 static 静态属性
// this.name='李四' // 不能 修改 "name" ,因为它是只读属性
}
getProtected() {
console.log(this.age); // ok
}
}
// 继承
class Child extends Person {
public name: string // public 默认成员修饰符 任何地方可以访问
constructor(name: string, age: number, sex: string) {
super(name, age, sex)
this.name = name
}
// getPrivate() {
// console.log(this.sex); //不能获取 属性“sex”为私有属性,只能在类“Person”中访问
// }
getProtected() {
console.log(this.age);
}
}
let chl = new Child('张三', 18, '男')
let per = new Person('张三', 18, '男')
// chl.sex 属性“sex”为私有属性,只能在类“Person”中访问
// chl.age 属性“age”受保护,只能在类“Person”及其子类中访问
Person.hobby //
Child.hobby //
export {
}
声明全局变量 declare
declare class声明全局类
declare enum 声明全局枚举类型
declare namespace 声明(含有子属性的)全局变量
//命名空间主要目的就是将一个模块内部再进行作用域的划分, 防止一些命名冲突
export namespace Time {
export function format(time: string){
return "2021-11-12"
}
}
export namespace Price {
export function format(price: number) {
return "$15,000"
}
}
模块
export default ES6 默认导出
export = commonjs 导出模块
require(’’) 引入
整体引入 import * as
import … require 是 ts 官方推荐的方式: