ctrl+k清屏
1.ts入门
1.安装VSCode
https://code.visualstudio.com/Download
2.安装Node.js为了安装npm
https://nodejs.org/en/download/
3.安装TypeScript编译器:npm install -g typescript
可以用tsc 文件.ts命令,根据ts生成js代码
node 文件.js 运行js
4.ts介绍
TypeScript 是 JavaScript 的类型的超集,是一种静态类型检查的语言,提供了类型批注和编译时类型检查;支持ES6语法,支持面向对象编程的概念,如类、接口、继承、泛型等; TypeScript 在编译阶段需要编译器编译成纯 JavaScript 来运行。
- ts和js的语言区别
js是脚本语言,ts是面向对象语言
js弱类型,ts强类型
ts增加了类和接口
2.优化编译
1.解决ts和js的冲突问题(比如命名)
tsc --init #生成配置文件 tsconfig.json
2.自动编译
tsc --watch
3.发出错误
tsc -noEmitOnError 文件.ts 提示错误并且不自动编译程js
3.tsconfig配置-修改完重新编译
tsconfig.json----“target”:“es5” 降级编译(考虑旧版本浏览器兼容)
strict:true 包含下面两种。是否忽略类型验证(false就会默认为any,破坏了ts类型检查)
noImplicitAny:true :不含隐藏的any(any检查,不用默认any)
strictNullChecks:true;严格空类型检验
strictPropertyInitialization:false:是否属性必须初始化(定义class),false不会检查属性
rootDirs|rootDir:ts目录
outDir:js输出目录
4.类型
-
boolean(布尔类型)
-
number(数字类型)
-
string(字符串类型)
-
数组:type[]、Array泛型
-
any:不希望某个特定值导致类型检查错误
-
null 类型数据加一个!可以排除null和undefined
-
undefined 类型数据加一个!可以排除null和undefined
-
enum Name {} 枚举-一组数值赋予友好的名字
-
void 不返回任何值
一个具有 void返回类型的上下文函数类型(type vf = () => void),在实现时,可以返回任何其他的值,但它会被忽略。
当一个字面的函数定义有一个 void 的返回类型时,该函数必须不返回任何东西。
-
object:任何不是基元的值:string\number\bigint\boolean\symbol\null\undefined;不同于{},不同于Object
-
unknown:代表任何值。这与 any 类型类似,但更安全,因为对未知 unknown 值做任何事情都是不合法的。
-
never: 是其他类型 (包括null和 undefined)的子类型,可以赋值给任何类型,代表从不会出现的值,类型表示永远不会被观察到的值(抛出异常|永远不触发)
-
Function :全局性的 Function 类型描述了诸如 bind、call、apply和其他存在于JavaScript中所有函数值的属性。它还有一个特殊的属性,即 Function 类型的值总是可以被调用;这些调用返回 any。
-
tuple(元组类型):表示一个已知元素数量和类型的数组,各元素的类型不必相同。
-
enum(枚举类型):一组数值赋予友好的名字
5.类型相关注意
-
: type 类型注释。可以指定具体字符、数字、true(文字类型 --有时候配合类型推断时使用)
-
?: type 可选类型 不传是undefined 调用方法可以用?.。可选属性使用时候在后面加个!表示肯定存在的
-
{x: numbr,y: number}对象
-
number | string 一个竖线-联合类型
-
type name = type 类型别名,name一般大写
-
类型判断 typeof对象的时候。排除null strs&&typeof
-
!:
- 属性或参数中使用
!:
——表示强制解析(告诉typescript编译器,这里一定有值),常用于vue-decorator中的@Prop - 变量后使用
!:
——表示类型推断排除null、undefined
- 属性或参数中使用
-
keyof 类型操作符
type Point = { x: number; y: number };
type P = keyof Point;//这时候p是’x’|'y’联合类型
const p1:P = ‘x’
const p2:P = ‘y’ -
在泛型约束中使用类型参数:key extends keyof Type
function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) { return obj[key] } let x = { a: 1, b: 2, c: 3, d: 4 } getProperty(x, 'a')
-
in用来类型缩小
type Fish = { swim: () => void } type Bird = { fly: () => void } type Human = { swim?: () => void; fly?: () => void } function move(animal: Fish | Bird | Human) { if ("swim" in animal) { // animal: Fish | Human return (animal as Fish).swim() } // animal: Bird | Human return (animal as Bird).fly() }
-
不太常用的原语
const oneHundred: bigint = BigInt(100) const anotherHundred: bigint = 100n //target:es2020才能使用 const firstName = Symbol("name") const secondName = Symbol("name") if (firstName === secondName) { console.log('ok') }
-
as type; 类型断言(用来转成更具体或者不太具体的版本,可以防止不可能的强制的发声)。会在编译时被删除,没有与类型断言相关联的类型检查。
//返回某种类型的HTMLElement
const myCanvas = document.getElementById ("main_canvas") as HTMLCanvasElement
const myCanvas = <HTMLCanvasElement>document.getElementById ("main_canvas")
const x = 'hello' as any
const y = 'hello' as unknown
6.接口(一般接口能实现,类型别名都可以)
类型别名创建后不能通过同一个名称扩展
-
类型使用(接口定义类型)
interface Point { x: number; y: number; } function printCoord(pt: Point) { console.log("坐标x的值是: " + pt.x); console.log("坐标y的值是: " + pt.y); } printCoord({ x: 100, y: 100 });
-
扩展接口
interface Animal { name: string } interface Bear extends Animal { honey: boolean } const bear: Bear = { name: 'winie', honey: true } console.log(bear.name) console.log(bear.honey)
类型别名实现接口扩展效果
//交叉点实现即& type Animal = { name: string } type Bear = Animal & { honey: boolean } const bear: Bear = { name: 'winnie', honey: true }
-
向现有接口类型添加字段
//向现有的类型添加字段,会起到合并效果 interface MyWindow { count: number } interface MyWindow { title: string } const w: MyWindow = { title: 'hello ts', count: 100 }
类型别名创建后不能通过同一个名称扩展
7.函数
-
普通定义函数类型:type GreetFunction = (a: string) => void
-
调用签名定义函数类型(对象方式定义)
type DescribableFunction = {
description: string //函数属性-函数可以直接调用
(someArg: number): boolean //入参(string)=>返回类型(boolean)
}//如上类型的函数
function fn1(n: number) {
console.log(n)
return true
}
fn1.description = ‘hello’ -
构造签名
需要new
class Ctor {
s: string
constructor(s: string) {
this.s = s
}
}type SomeConstructor = {
new (s: string): Ctor
}function fn(ctor: SomeConstructor) {
return new ctor(‘hello’)
}interface CallOrConstructor {
new (s: string): Date
(n?: number): number
}function fn(date: CallOrConstructor) {
let d = new date(‘2021-12-20’) //构造签名
let n = date(100) //调用签名
} -
泛型
编写优秀函数的三个准则
1.尽量使用本身,而不是类型约束;
2.尽量少的使用类型参数;
3.类型参数是用来关联多个值的类型的,类型如果只使用一次,每笔用用泛型
-
类型判断 ,<Type1,Type2> 尽量只使用本身
function firstElement(arr: Type[]): Type | undefined {
return arr[0]
}firstElement([‘a’, ‘b’, ‘c’])
firstElement([1, 2, 3])
firstElement([]) -
限制条件 <Type extends { length: number }>类型必须有length属性
function longest<Type extends { length: number }>(a: Type, b: Type) {
if (a.length >= b.length) {
return a
} else {
return b
}
}const longerArray = longest([1, 2], [2, 3, 4])
-
指定类型参数 <string | number> 不推荐,指定第一个是string,第二个是number
function combine(arr1: Type[], arr2: Type[]): Type[] {
return arr1.concat(arr2)
}const arr = combine<string | number>([“string”], [1, 2, 3])
console.log(arr)
-
-
可选参数
?: 可选参数;默认值:number=100
为回调写一个函数的时候,永远(尽量)不要写可选参数
-
函数重载
函数重载定义如何调用,函数实现才是真正的函数实现,函数实现参数得兼容函数重载
编写好的重载
总是倾向于使用联合类型的参数而不是重载参数
//函数重载 function makeDate(timestamp: number): Date
//函数重载 function makeDate(m: number, d: number, y: number): Date//函数实现 function makeDate(mOrTimestamp: number, d?: number, y?: number): Date {
if (d !== undefined && y !== undefined) {
return new Date(y, mOrTimestamp, d)
} else {
return new Date(mOrTimestamp)
}
}const d1 = makeDate(12345678)
const d2 = makeDate(5, 6, 7)
const d3 = makeDate(5, 9) //报错 -
rest parameters 形参展开方式
//形参展开
function multiply(n: number, …m: number[]) {
return m.map( x => n * x )
}const a = multiply(10, 1, 2, 3, 4, 60, 100)
console.log(a)
//实参展开
const arr1 = [1, 2, 3]
const arr2 = [4, 5, 6]
arr1.push(…arr2)// const args = [8, 5]
// const angle = Math.atan2(…args) //报错const args = [8, 5] as const
const angle = Math.atan2(…args)//参数结构
type ABC = { a: number, b: number, c: number }
function sum({ a, b, c }: ABC) {
console.log(a + b + c)
}sum({
a: 10,
b: 3,
c: 9
}) -
void
一个具有 void返回类型的上下文函数类型(type vf = () => void),在实现时,可以返回任何其他的值,但它会被忽略。
当一个字面的函数定义有一个 void 的返回类型时,该函数必须不返回任何东西。
type voidFunc = () => void
const f1:voidFunc = () => {
return true
}const f2:voidFunc = () => true
const f3:voidFunc = function() {
return true
}const v1: void = f1()
const v2 = f2()
const v3 = f3()// 下面会报错
function f4(): void {
return true
}const f5 = function(): void {
return true
}
8.对象类型
-
定义
//匿名方式定义对象类型 function greet(person: { name: string, age: number }) { return 'Hello ' + person.name } //接口方式 interface Person { name: string age: number } function greet(person: Person) { return 'Hello ' + person.name } //类型别名 type Person = { name: string age: number } function greet(person: Person) { return 'Hello ' + person.name }
-
属性修改器
可选属性 :配合默认值
interface PaintOptions {
xPos?: number,
yPos?: number
}function paintShape({ xPos: number = 0, yPos = 0 }: PaintOptions) {
// let xPos = opts.xPos === undefined ? 0 : opts.xPos
// let yPos = opts.yPos === undefined ? 0 : opts.yPos
console.log(number)
}只读属性:readonly
加了readonly不能修改,引用对象是不能修改引用地址
readonly类型可以复制可写类型
索引签名:不能知道一个类型的所有属性名称
//索引签名只有number和string interface StringArray { [index: number]: string } const myArray: StringArray = ['a', 'b'] const secondItem = myArray[0] interface TestString { [props: string]: number } let testString: TestString = { x: 100, y: 200, // aaa: 'aaa' } interface NotOkay { [index: string]: number | string length: number name: string } let notOkay: NotOkay = { x: 100, length: 100, name: 'felix' }
-
扩展类型
interface Colorful { color: string } interface Circle { radius: number } interface ColorCircle extends Colorful, Circle {} const cc: ColorCircle = { color: 'red', radius: 100 }
-
交叉类型
interface Colorful { color: string } interface Circle { radius: number } type ColorfulCircle = Colorful & Circle const cc: ColorfulCircle = { color: 'red', radius: 100 }
-
扩展类型和交叉类型主要区别
interface可以重名合并,类型别名可以避免命名冲突
-
泛型类型对象
// interface Box<Type> { // contents: Type // } // 通用类型 以下写法很好 type OrNull<Type> = Type | null type OneOrMany<Type> = Type | Type[] type OneOrManyOrNull<Type> = OrNull<OneOrMany<Type>> type OneOrManyOrNullString = OneOrManyOrNull<string>
9.从类型中创建类型
-
泛型*
function identity<Type>(arg: Type): Type { return arg } identity<string>("string") identity("string") //泛型类型 let myIdentity: <Type>(arg: Type) => Type = identity let myIdentity: <Input>(arg: Input) => Input = identity let myIdentity: { <Type>(arg: Type): Type } = identity interface GenericIdentityFn { <Type>(arg: Type): Type } let myIdentity: GenericIdentityFn = identity interface GenericIdentityFn<Type> { (arg: Type): Type } let myIdentity: GenericIdentityFn<string> = identity //泛型类 class GenericNumber<NumType> { zeroValue: NumType add: (x: NumType, y: NumType) => NumType } let myGeneric = new GenericNumber<number>() myGeneric.zeroValue = 0 myGeneric.add = function (x, y) { return x + y } //泛型约束 类型必须有extends里面的属性 interface Lengthwise { length: number } //Type必须有length属性 function loggingIdentity<Type extends Lengthwise>(arg: Type): Type { arg.length return arg } loggingIdentity(['hello', 'world']) //在泛型约束中使用类型参数 key extends keyof Type key类型一定属于Type类型的某个key function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) { return obj[key] } let x = { a: 1, b: 2, c: 3, d: 4 } getProperty(x, 'a') //在泛型中使用类类型 c是个类类型 c: { new (): Type } function create<Type>(c: { new (): Type }): Type { return new c() } class BeeKeeper { hasMask: boolean = true } class ZooKeeper { nametag: string = 'Mikle' } class Animal { numLegs: number = 4 } class Bee extends Animal { keeper: BeeKeeper = new BeeKeeper() } class Lion extends Animal { keeper: ZooKeeper = new ZooKeeper() } function createInstance<A extends Animal>(c: new () => A): A { return new c() } createInstance(Lion).keeper.nametag createInstance(Bee).keeper.hasMask createInstance(BeeKeeper)//类型约束不是没有Animal的属性
-
keyof 类型操作符
// type Point = { // x: number, // y: number // } // type P = keyof Point // const p1:P = 'x' // const p2:P = 'y' // const p3:P = 'z' type Arrayish = { [n: number]: unknown } type A = keyof Arrayish const a:A = 0 type Mapish = { [k: string]: boolean //索引类型是string可以是number或者string } type M = keyof Mapish const m1:M = 's' const m2:M = 100
-
typeof类型操作符
let s = 'hello' let n: typeof s //返回s类型 n = 'hello' n = 100 // type Predicate = (x: unknown) => boolean // type K = ReturnType<Predicate> // function f() { // return { // x: 10, // y: 3 // } // } // type P = ReturnType<typeof f> //类型是{x:number,y:number}
-
索引访问类型 //索引的时候只能使用类型
// type Person = { // age: number, // name: string, // alive: boolean // } // type Age = Person['age'] // let age: Age = '90' interface Person { name: string age: number alive: boolean } // type I1 = string | number type I1 = Person['age' | 'name'] const i11: I1 = 100 const i12: I1 = '' // const i13: I1 = true // type I2 = string | number | boolean type I2 = Person[keyof Person] const I21: I2 = '' const I22: I2 = 100 const I23: I2 = true // const I24: I2 = {} type AliveOrName = 'alive' | 'name' type I3 = Person[AliveOrName] const I31: I3 = true const I32: I3 = 'hello' // const I33: I3 = 100 // type I4 = Person['alve'] const MyArray = [ { name: 'Alice', age: 15 }, { name: 'Bob', age: 23 }, { name: 'Eve', age: 38 } ] // type Person = { name: string, age: number } type Person = typeof MyArray[number] const p:Person = { name: 'xiaoqian', age: 11, // alive: true } type Age = typeof MyArray[number]['age'] const age: Age = 11 type Age2 = Person['age'] const age2: Age2 = 300 // const key = 'age' type key = 'age' type Age3 = Person[key]
-
条件类型
interface Animal { live(): void } interface Dog extends Animal { woof(): void } // type Example1 = number type Example1 = Dog extends Animal ? number : string // type Example2 = string type Example2 = RegExp extends Animal ? number : string 条件类型约束 // type MessageOf<T> = T['message'] // type MessageOf<T extends { message: unknown }> = T['message'] type MessageOf<T> = T extends { message: unknown } ? T['message'] : never interface Email { message: string } interface Dog { bark(): void } // type EmailMessageContents = string type EmailMessageContents = MessageOf<Email> const emc: EmailMessageContents = 'balabala...' type DogMessageContents = MessageOf<Dog> const dmc: DogMessageContents = 'error' as never //在条件类型内推理 infer type GetReturnType<Type> = Type extends (...args: never[]) => infer Return ? Return : never // type Num = number type Num = GetReturnType<() => number> let num: Num = 100 // type Str = string type Str = GetReturnType<(x: string) => string> let str: Str = '' // type Bools = boolean[] type Bools = GetReturnType<(a: boolean, b: boolean) => boolean[]> let bools: Bools = [true, false] // type Never = never type Never = GetReturnType<string> let nev: Never = 'error' as never
-
分布式条件类型
type ToArray<Type> = Type extends any ? Type[] : never // type StrArrOrNumArr = string[] | number[] type StrArrOrNumArr = ToArray<string | number> let saon: StrArrOrNumArr = [1,2,3] type ToArrayNonDist<Type> = [Type] extends [any] ? Type[] : never //type StrArrOrNumArr = (string | number)[] type StrArrOrNumArr = ToArrayNonDist<string | number> let saon: StrArrOrNumArr = [1,'22']
10.类
-
类属性
class Point { x y constructor() { this.x = 0 this.y = 0 } } const pt = new Point() pt.x = 1 pt.y = 1 console.log(pt.x) console.log(pt.y) class OkGreeter { name!: string//类型断言可以不初始化.表示强制解析(告诉ts编译器,这里一定有值) }
-
readonly
class Greeter { readonly name: string = 'world'//只可以在构造器初始化 constructor(otherName?: string) { if (otherName !== undefined) { this.name = otherName } } err() { // this.name = 'not ok' } } const g = new Greeter('hello') // g.name = 'a'
-
构造器
class Point { x: number y: number constructor (x: number = 0, y: number = 0) { this.x = x this.y = y } }
-
方法
类内部读取属性要加this class Point { x: number = 10 y: number = 10 scale(n: number): void { this.x *= n this.y *= n } } const p = new Point() p.scale(10) console.log(p.x) console.log(p.y)
-
Getters / Setters
如果存在 get,但没有set,则该属性自动是只读的
如果没有指定setter参数的类型,它将从getter的返回类型中推断出来
访问器和设置器必须有相同的成员可见性class C { _length = 0 get length() { return this._length } set length(value) { this._length = value } } let c: C = new C() console.log(c.length) c.length = 100 c.length = 'hello' console.log(c.length)
-
索引签名
class MyClass { [s: string]: boolean | ((s: string) => boolean) //属性 x = true //函数 check(s: string) { return this[s] as boolean } }
-
类继承-implements子句
//实现类型不一定与接口类型一致;可选属性可以不实现 interface Checkable { check(name: string) : boolean } class NameChecker implements Checkable { //check(s: string|number) { check(s: string) { return s.toLowerCase() === 'ok' } }
-
extends
//基类 class Animal { move() { console.log('Moving along!') } } //派生类,基类的子类型 class Dog extends Animal { woof(times: number) { for (let i = 0; i < times; i++) { console.log('woof!') } } } const d = new Dog() d.move() d.woof(3)
-
方法重写
//派生类是基类的子对象|子类型 //派生类同名方法覆盖基类方法。 //派生类一定要和基类做兼容。 //greet(name: string)这样子就不兼容基类 class Base { greet() { console.log('Hello World') } } class Derived extends Base { greet(name?: string) { if (name === undefined) { super.greet() } else { console.log(name.toUpperCase()) } } } const d = new Derived() d.greet() d.greet('reader') //派生类是基类的子对象|子类型 const b: Base = d
-
初始化顺序
基类的字段被初始化
基类构造函数运行
派生类的字段被初始化
派生类构造函数运行 -
继承内置类型
//es5兼容性解决 class MsgError extends Error { constructor(m: string) { super(m) // 明确的设置原型 Object.setPrototypeOf(this, MsgError.prototype) } sayHello() { return 'hello ' + this.message } } const msgError = new MsgError('hello') console.log(msgError instanceof MsgError)
-
成员的可见性
public(默认):公开的,默认值。任何对象在任何地方都可以访问(类内部,子类,实例上)
protected:受保护的。能在当前类或者子类中进行访问
子类中可以修改父类中某个属性的可见性
class Base { protected m = 10 } class Derived extends Base { public m = 15 } const d = new Derived() console.log(d.m)
private:私有的。只能在当前类中进行访问,不允许子类、实例访问
-
静态成员
不需要实例化,直接通过类名访问。
静态成员可以继承,可以配合可见性使用
class MyClass { private static x = 0 static printX() { console.log(MyClass.x) } } console.log(MyClass.x) MyClass.printX() class Base { static getGreeting() { return 'hello world' } } class Derived extends Base { myGreeting = Derived.getGreeting() }
-
类里的static区块
//仅能类内部使用 class Foo { static #count = 0 get count() { return Foo.#count } static { try { const lastInstance = { length: 100 } Foo.#count += lastInstance.length } catch {} } } //以下调用报错 //Foo.#count
-
泛型类
静态成员不能赋值泛型
class Box<Type> { contents: Type; constructor(value: Type) { this.contents = value; } } const b = new Box("hello!")
-
类运行时候的this
// 解决this指向问题:1.箭头函数(得保证this正确;比较耗内存,类实例得有副本;不能在派生类中使用super调用父类方法,原型链中无法获取基类方法);2.this参数(每个类定义只有一个函数被分配,而不是每个实例创建一个函数;可以super调用) class MyClass { name = 'MyClass' //getName() { // return this.name //} // getName = () => { //解决方案1 // return this.name // } //getName(this: MyClass) {//解决方案2//谁调用就访问谁 // return this.name //} } const c = new MyClass() // console.log(c.getName()) //'MyClass' // const obj = { // name: 'obj', // getName: c.getName // } // console.log(obj.getName())//'obj' const g = c.getName // console.log(c.getName()) console.log(g())
-
this类型
派生类后基类的this依旧指向派生类
-
基于类型守卫的this
this is Type ;this配合守卫可以缩小类型
class FileSystemObject { isFile(): this is FileRep { return this instanceof FileRep } isDirectory(): this is Directory { return this instanceof Directory } isNetworked(): this is Networked & this { return this.networked } constructor (public path: string, private networked: boolean) {} } class FileRep extends FileSystemObject { constructor(path: string, public content: string) { super (path, false) } } class Directory extends FileSystemObject { children: FileSystemObject[] constructor() { super('', false) this.children = [] } } interface Networked { host: string } const fso: FileSystemObject = new FileRep('foo/bar.txt', 'foo') if (fso.isFile()) { // const fso: FileRep fso.content } else if (fso.isDirectory()) { // const fso: Directory fso.children } else if (fso.isNetworked()) { // const fso: Networked & FileSystemObject fso.host } class Box <T> { value?: T hasValue(): this is { value: T } { return this.value !== undefined } } const box = new Box() box.value ='hello' if (box.hasValue()) { console.log(box.value) }
-
参数属性
构造函数入参属性前加入修饰符:public readonly,protectd,private
class Params { constructor (public readonly x: number, protected y: number, private z: number) { this.x = x } } const p = new Params(100, 300, 400) console.log(p.x) // p.x = 200 //p.y //p.z
-
类表达式
const someClass = class<Type> { content: Type constructor(value: Type) { this.content = value } } const m = new someClass('hello') console.log(m.content)
-
抽象类和成员
abstract:没有提供实现的方法或者字段,这些成员必须存在于一个抽象类中。不能直接实例化,抽象类的作用是作为子类的基类,实现所有抽象成员。
当一个类没有抽象成员时,我们就说他是具体的。
abstract class Base { abstract getName(): string printName() { console.log(this.getName()) } } class Derived extends Base { getName () { return 'world' } } const b = new Derived() b.getName() b.printName() function greet(ctor: new() => Base) { const instance = new ctor() instance.printName() } greet(Derived)
-
类之间的关系
//类属性和类型一样 class Point1 { x = 0 y = 0 } class Point2 { x = 0 y = 0 } const p: Point1 = new Point2() //Emplyee 是 Person子类 class Person { name: string = '' age: number = 100 } class Emplyee { name: string = 'felixlu' age: number = 23 salary: number = 10 } const p: Person = new Emplyee()
11.模块
在TypeScript中编写基于模块的代码时,有三个主要方面需要考虑:
语法:我想用什么语法来导入和导出东西?
模块解析:模块名称(或路径)和磁盘上的文件之间是什么关系?
模块输出目标:我编译出来的JavaScript模块应该是什么样子的?
-
es模块化
//导出1 export default function helloWorld() { console.log('Hello, World') } //导出2 export var pi = 3.14 export let squareTwo = 1.41 export const phi = 1.61 export class RandomNumberGenerator {} export function absolute(num: number) { if (num < 0) return num * -1 return num } //导入 import hello from './hello' import { pi, phi, absolute } from './maths' hello() console.log(pi) console.log(absolute(phi))
-
额外的导入语法
//导出 export const pi = 3.14 export default class RandomNumberGenerator {} //导入起别名 import RNGen, { pi as π } from './maths' //import * as math from './maths' const rnGen = new RNGen() //console.log(math.pi) //const rnGen = new math.default()
-
typeScript特定的es模块语法
//导出 export type Cat = { breed: string yearOfBirth: number } // export type Dog = { // breeds: string[] // yearOfBirth: number // } export const createCatName = () => 'fluffy' export interface Dog { breeds: string[] yearOfBirth: number } //导入 import type { Cat, Dog } from './animal' import { createCatName } from './animal' import { createCatName, type Cat, type Dog } from './animal' type Animals = Cat | Dog createCatName()
-
commonJs语法
//导出module.exports;exports function absolute(num: number) { if(num < 0) return num * -1 return num } module.exports = { pi: 3.14, squareTwo: 1.41, phi: 1.61, absolute } // exports.absolute = absolute //导入 const maths = require('./maths') console.log(maths.pi)