typescript的基础语法

参考网站:http://www.jspang.com/detailed?id=63#toc298

一.安装typescript

1.首先要安装Nodejs,然后用命令行查看node和npm是否安装成功
在这里插入图片描述
2.然后命令安装typescript

npm install -g typescript

3.输入tsc -v看看是否安装成功
在这里插入图片描述
注意:
如果安装成功,但tsc -v报错,有可能是环境变量的问题。
之前是这个方法解决的

二.运行第一个ts文件

在ts文件夹下建了个demo1.ts,如果直接用node demo1.js的命令会报错。需要转换一下,先tsc demo1.ts,这样ts文件夹会多一个对应的demo1.js文件,然后运行这个文件,node demo1.js.
在这里插入图片描述

1.运行的第一种方法:先转为js,再运行

先tsc demo1.ts,然后node deo1.js
在这里插入图片描述

2.另外一种方法,全局安装ts-node

npm install -g ts-node

本来可以直接起运行命令就可以的:ts-node demo1.ts

**注意:**但我这里命令跑起来的时候会报错,报一些关于node_module没找到关于@types/node这一类的错。
然后百度查了这两个命令:

npm i d3 @types/d3
npm install @types/node

然后再起就成功了

ts-node demo1.ts

在这里插入图片描述

三.语法

1.静态语法 static typing

1.1特点:

1)静态类型一旦声明了,类型就无法改变。

如下,声明了是数字,就不能改成字符串
在这里插入图片描述

2)自动携带相关类型的属性

在这里插入图片描述

3)如何自定义自定义静态类型
interface XiaoJieJie{
    uname:string,
    age:number
}
const xiaohong:XiaoJieJie={
    uname:'小红',
    age:18
}
console.log(xiaohong.age)

打印:
在这里插入图片描述

1.2.分类:

1.2.1基础静态类型

number,sring,boolean,null,undefined,void,symbol

const count : number = 98;
const myName : string ='jspang'
1.2.2对象静态类型

包括普通对象类型,数组类型,类类型,函数类型

//对象
const xiaoJieJie:{
    name:string,
    age:number
}={
    name:'大脚',
    age:18
}
//数组
//string []表示后面是数组,而且里面都是字符串
const xiaoJieJies : string []=['谢大脚','谢小脚','谢中脚']


//类
//表示有一个Person类,dajiao必须是person类的对象
class Person{}
const dajiao : Person = new Person()

//函数
//表示必须是函数,而且返回结果必须是字符串
const JianXiaoJieJie : ()=>string=()=>{return '大脚'}

2.类型注解和类型推断

2.1类型注解

鼠标悬停变量上,就会出现他的类型注解
在这里插入图片描述

2.2类型判断

没有写明类型,代码会自动分析type的类型
在这里插入图片描述

2.3工作使用问题(潜规则)

1)如果ts能够自动分析变量类型,我们就什么也不需要做了;
在这里插入图片描述
在这里插入图片描述

2)如果ts无法分析变量类型的话,我们就需要使用类型注解
示例:
这里one和two没有确定是什么类型的,所以total是any,也就是任何类型都可以。
在这里插入图片描述
这里确定了one和two的类型,所以total的类型是确定的,也是number
在这里插入图片描述

有一种函数变量参数的写法:
这样直接写会报错
在这里插入图片描述
需要这样写:

function add({one , two} : {one : number,two : number}){
    return one + two
}
const total = add({one : 1 ,two : 2})

可以确定one和two这两个参数的类型
在这里插入图片描述

2.4函数返回类型的注解

2.4.1参数后面加类型

如下:如果在等式后面加了一个‘’,但要求最后的total是number类型的,就需要返回类型的注解。

function getTotal(one : number,two : number) {
    return one + two + '';
}
const total  = getTotal(1,2)

方法一,直接定义total的类型
在这里插入图片描述

方法二:在参数后面加类型
在这里插入图片描述

2.4.1 void

添加了void就不能有返回值,即使是空字符串也不可以。
在这里插入图片描述

2.4.2never

东西永远执行不完, 用never。比如:报错的代码,死循环

//报错
function errorFunction() :never {
    throw new Error()
    console.log('hello world')
}

//死循环
function forNever(): never {
    while(true){}
    console.log('hello world')
}

2.5数组类型注解的方法

const numberArr : number[] = [1,2,3]
const stringArr : string[] =['a','b','c']
const undefinedArr : undefined[] = [undefined,undefined]//这种后面就必须全部是undefiend,否则就报错
const arr :(string | number)[]=[1,'a',2]//这种就是字符串和数字都可以
const xiaoJieJie :{name:string,age:number}[]=[
    {name:'六月',age:18},
    {name:'刘洋',age:28}
]

对象数组还可以用类型别名的方法:

type Lady={name:string,age:number}
const xiaoJieJie :Lady[]=[
    {name:'六月',age:18},
    {name:'刘洋',age:28}
]

或者

class Madam{
    name:string;
    age:number
}
const xiaoJieJie :Madam[]=[
    {name:'六月',age:18},
    {name:'刘洋',age:28}
]

3.元组的使用和类型约束

元组的使用情况比较少

const xiaoJieJie : [string,string,number]=['a','b',12]

const xiaoJieJies :[string,string,number][]=[
    ['a','b',12],
    ['a','b',12],
    ['a','b',12],
]

4.接口interface

用法:参数有重复的时候,就定义一个接口的方式约束它的类型。

原始写法:

const screenResume=(name:string,age:number,bust:number)=>{
    age < 24 && bust >= 90 && console.log(name + '进入面试')
    age >= 24 || bust < 90 && console.log(name + '你被淘汰')
}
const getResume=(name:string,age:number,bust:number)=>{
    console.log(name + '年龄是' + age)
    console.log(name + '胸围是' + bust)
}
screenResume('大脚',18,94)
getResume('大脚',18,94)

在这里插入图片描述

4.1用接口的写法优化:

interface Girl{
    name:string;
    age:number;
    bust:number;//注意这里使用分号结尾,为不是逗号
}

const girl={
    name:'大脚',
    age:18,
    bust:94
}
//把girl传递进来,符合Girl接口的模式
const screenResume=(girl:Girl)=>{
    girl.age < 24 && girl.bust >= 90 && console.log(girl.name + '进入面试')
    girl.age >= 24 || girl.bust < 90 && console.log(girl.name + '你被淘汰')
}
const getResume=(girl:Girl)=>{
    console.log(girl.name + '年龄是' + girl.age)
    console.log(girl.name + '胸围是' + girl.bust)
}
screenResume(girl)
getResume(girl)

4.2 和类型别名的区别

其实这个和类型别名有点像,就是之前type的那个,他们之间的区别在于:类型别名后面可以跟着字符串也就是类型,但接口后面必须是个对象

4.3 ?表示可选值

interface Girl{
    name:string;
    age:number;
    bust:number;
    waistline?:number //表示可选参数
}

const girl={
    name:'大脚',
    age:18,
    bust:94,
    waistline:12//这里有值或没值都可以
}
//把girl传递进来,符合Girl接口的模式
const screenResume=(girl:Girl)=>{
    girl.age < 24 && girl.bust >= 90 && console.log(girl.name + '进入面试')
    girl.age >= 24 || girl.bust < 90 && console.log(girl.name + '你被淘汰')
}
const getResume=(girl:Girl)=>{
    console.log(girl.name + '年龄是' + girl.age)
    console.log(girl.name + '胸围是' + girl.bust)
    girl.waistline&&console.log(girl.name+'腰围是'+girl.waistline)
}
screenResume(girl)
getResume(girl)

在这里插入图片描述
还有一种写法,就是所有类型都可以添加

4.4 [propname:string]:any表示名称是string类型,值是任何类型都可以

interface Girl{
    name:string;
    age:number;
    bust:number;
    waistline?:number; //表示可选参数,
   [propname:string]:any
}

const girl={
    name:'大脚',
    age:18,
    bust:94,
    waistline:12,//这里有值或没值都可以
    sex:'女'
}
//把girl传递进来,符合Girl接口的模式
const screenResume=(girl:Girl)=>{
    girl.age < 24 && girl.bust >= 90 && console.log(girl.name + '进入面试')
    girl.age >= 24 || girl.bust < 90 && console.log(girl.name + '你被淘汰')
}
const getResume=(girl:Girl)=>{
    console.log(girl.name + '年龄是' + girl.age)
    console.log(girl.name + '胸围是' + girl.bust)
    girl.waistline&&console.log(girl.name+'腰围是'+girl.waistline)
    girl.sex&&console.log(girl.name+'性别是'+girl.sex)
}
screenResume(girl)
getResume(girl)

4.5 类受接口的约束implements

接口不仅能限制对象,还可以限制类,类必须带着些属性。

interface Girl{
    name:string;
    age:number;
    bust:number;
    waistline?:number; //表示可选参数,
    [propname:string]:any;
    say():string;//必须有个say方法,返回值是string类型
}
class XiaoJieJie implements Girl{
    name='六月';
    age=18
    bust=90
    say(){
        return '你好,洗浴'
    }
}

4.6接口间的继承

interface Teacher extends Girl实现继承

interface Girl{
    name:string;
    age:number;
    bust:number;
    waistline?:number; //表示可选参数,
    [propname:string]:any;
    say():string;//必须有个say方法,返回值是string类型
}
//teacher继承Girl。teacher自带teach方法
interface Teacher extends Girl{
    teach():string;
}



const girl={
    name:'大脚',
    age:18,
    bust:94,
    waistline:12,//这里有值或没值都可以
    sex:'女',
    say(){
        return '欢迎光临,红浪漫洗浴'
    },
    teach(){
        return '我来教你们做'
    }
}
//把girl传递进来,符合Girl接口的模式
const screenResume=(girl:Girl)=>{
    girl.age < 24 && girl.bust >= 90 && console.log(girl.name + '进入面试')
    girl.age >= 24 || girl.bust < 90 && console.log(girl.name + '你被淘汰')
}
//这里girl要有teacher属性,就要在girl里面加teach方法
const getResume=(girl:Teacher)=>{
    console.log(girl.name + '年龄是' + girl.age)
    console.log(girl.name + '胸围是' + girl.bust)
    girl.waistline&&console.log(girl.name+'腰围是'+girl.waistline)
    girl.sex&&console.log(girl.name+'性别是'+girl.sex)
}
screenResume(girl)
getResume(girl)

5.类的概念和使用

5.1基本使用

跟es6差不多

class Lady{
    content='帅哥'
    sayHello(){
        return this.content
    }
}
class XiaoJieJie extends Lady{
    sayLove(){
        return 'I LOVE YOU'
    }
}
console.log(new XiaoJieJie().sayHello())
console.log(new XiaoJieJie().sayLove())

在这里插入图片描述

5.2类的重写

把父类的方法或者属性拿出来重新定义

class Lady{
    content='帅哥'
    sayHello(){
        return this.content
    }
}
class XiaoJieJie extends Lady{
    //重写
    sayHello(){
        return 'hi,honey'
    }
    sayLove(){
        return 'I LOVE YOU'
    }
}
console.log(new XiaoJieJie().sayHello())
console.log(new XiaoJieJie().sayLove())

5.3super关键字

super.取父级的方法

class Lady{
    content='Hi,帅哥'
    sayHello(){
        return this.content
    }
}
class XiaoJieJie extends Lady{
    //super关键字点父级的方法,取父级的方法+值
    sayHello(){
        return super.sayHello()+'你好'
    }
    sayLove(){
        return 'I LOVE YOU'
    }
}
console.log(new XiaoJieJie().sayHello())
console.log(new XiaoJieJie().sayLove())

5.4类的访问类型

类的三种访问类型:private(私有的),protected(保护的),public(公有的)
类的内部和类的外包,大括号之内的是类的内部

5.4.1public共用的,在类的内部和类的外部都是允许调用的

Person不定义,默认定义成public类型的

class Person{
    name : string = '';
    sayHello(){
        console.log(this.name+'say:hello')
    }
}
const person = new Person()
person.name='jspang'
person.sayHello()
console.log(person.name)

相当于:

class Person{
    public name : string = '';
    public sayHello(){
        console.log(this.name+'say:hello')
    }
}
const person = new Person()
person.name='jspang'
person.sayHello()
console.log(person.name)

在这里插入图片描述

5.4.2private只允许类的内部使用

设置私有,外部调用就直接报错
在这里插入图片描述

5.4.3protected

protected不允许在类的外部使用,但在继承的时候运行在类的外部使用
在这里插入图片描述

5.5类的构造函数

构造函数中的特殊使用:

示例一:
constructor的简写

class Person{
    //第一种写法:
    // public name : string;
    // constructor(name:string){
    //     this.name=name
    // }
    //第二种写法:
    constructor(public name:string){}
}
const person = new Person('jspang')
console.log(person.name)

示例二:
只要子类中有constructor,就必须要通过super调父级,否则会报错

class Person{
//父类如果不写,这个constructor也是有的,就是为空constructor(){}
    constructor(public name:string){}
}
class Teacher extends Person{
    //子类也有自己的constructor的话,必须要通过super调父级的函数
    constructor(public age:number){
        super('jspang')
    }
}
const teacher = new Teacher(18)
console.log(teacher.age)
console.log(teacher.name)

5.6private的使用

功能在于封装一个方法,然后通过getter或者setter的形式访问这个属性
如果直接访问会报错
在这里插入图片描述
使用方式:
get获取值

class xiaoJieJie{
    constructor(private _age:number){}
    get age(){
        return this._age-10
    }
}
const dajiao = new xiaoJieJie(28)
console.log(dajiao.age)

在这里插入图片描述
set进行赋值

class xiaoJieJie{
    constructor(private _age:number){}
    get age(){
        return this._age-10
    }
    set age(age:number){
        this._age=age+3
    }
}
const dajiao = new xiaoJieJie(28)
dajiao.age=25
console.log(dajiao.age)

在这里插入图片描述

5.7静态类的使用

以前的写法:

class Girl{
    sayLove(){
        return 'I love you'
    }
}
const girl =new Girl()
console.log(girl.sayLove())

使用static不需要实例,就可以直接调用方法

class Girl{
   static sayLove(){
        return 'I love you'
    }
}

console.log(Girl.sayLove())

5.8只读属性

原本的类是可以修改的

class Person{
    constructor (public name:string){}
}
const person =new Person('jspang')
person.name='谢广坤'
console.log(person.name)

只读属性的设置,局部可以修改,修改就会报错
在这里插入图片描述

5.9抽象类abstract

继承抽象类,子类就必须带抽象类的方法,否则就报错

abstract class Girl{
    //抽象类的方法
    abstract skill()
}
class Waiter extends Girl{
    skill(){
        console.log('大爷,喝水')
    }
}
class BaseTeacher extends Girl{
    skill(){
        console.log('大爷,泰式按摩')
    }
}
class seniorTeacher extends Girl{
    skill(){
        console.log('大爷,SPA按摩')
    }
}

6.tsconfig.json文件

是ts的编译配置文件,也就是把ts编译成ts都靠这个文件

6.1怎么生成tsconfig.json文件

在终端输入:

tsc -init

在这里插入图片描述
就会在文件的根目录生成一个tsconfig.json文件

6.2如何让tsconfig.json生效

输入命令tsc demo1.ts虽然编译出来了一个demo1.js文件,但没有走tsconfig.json配置
而输入

tsc

是可以的,走了tsconfig.json的配置

ts-node demo1.ts会走tsconfig.json的配置

6.3分析tsconfig.json文件

6.3.1 include,exclude多个文件中编译指定文件

默认情况下是输入tsc命令,文件下的所以ts文件全部编译出来
但可以通过include[“demo1.ts”]这种指定编译的文件(和files的用法一样,也是包含的文件名字进行编译)
或者exclue[“demo2.ts”]排除指定文件,编译剩余的所有文件

6.3.2 strict代表js的编译和书写规范 。这个为true下面所有的都是true,设置也无用

strict下的其他配置:
1)noImplicitAny:设置为false表示允许你的注解any不用特意标明
默认为true的情况下这样直接写就会报错,必须要写清楚name : any才不报错
在这里插入图片描述
但设置noImplicitAny:false就不报错了

2)“strictNullChecks”: true
表示不允许有null只出现,出现就会报错
在这里插入图片描述
3)入口文件和编译文件
outDir:编译文件路径

"outDir": "./build",

rootDir:ts文件路径

"rootDir": "./src"

4)“sourceMap”: true开启就会生成一个.map文件
把源文件和生成的文件有了一个对应关系,生产文件错了,可以在ts文件上改错。

5)“noUnusedLocals”: true开启的话项目中没有使用的变量,编译打包的时候就会报错,提示你有无用变量。
“noUnusedParameters”: true, 没有用的方法在编译打包的时候就会提示出来

7.联合类型和类型保护(类型守护)

有联合类型存在的情况下才需要类型保护
参数有两种以上的方法叫联合类型
技师没有say方法的就会报错,这个时候就要用到类型保护。

第一种方式 as:

interface Waiter{
    anjiao:boolean;
    say:()=>{};
}
interface Teacher{
    anjiao:boolean;
    skill:()=>{};
}
function judgeWho(animal:Waiter | Teacher){
    //会按脚就是服务可以调用say方法,不会按脚就是技师可以调用skill方法
    if(animal.anjiao){
        (animal as Teacher).skill()
    }else{
        (animal as Waiter).say()
    }
}

第二种方法 in:

interface Waiter {
    anjiao: boolean;
    say: () => {};
}
interface Teacher {
    anjiao: boolean;
    skill: () => {};
}
function judgeWho(animal: Waiter | Teacher) {
    //会按脚就是服务可以调用say方法,不会按脚就是技师可以调用skill方法
    if("skill" in animal){
        animal.skill();
    }else{
        animal.say()
    }
}

第三种方法: typeof
如果是string方法,直接相加就会报错
在这里插入图片描述
这样写就不会报错:

function add(first :string | number,second :string |number){
    if(typeof first ==='string'|| typeof second ==='string'){
        return `${first}${second}`
    }else{
        return first + second;
    }
}

第四种方法:instanceof 只能用于类
这个类可能是普通类,也可能是numberObj类

class NumberObj{
    count:number;
}
function addObj(first :object | NumberObj,second :object |NumberObj){
    if(first instanceof NumberObj && second instanceof NumberObj){
        return first.count + second.count;
    }
    return 0;
}

8.Enum 枚举类型

初级程序员的写法:

function getServe(status : number){
    if(status ===0){
        return 'massage'
    }else if(status ===1){
        return 'SPA'
    }else if(status ===2){
        return 'dabaojian'
    }
}
const result=getServe(0)
console.log(`我要去${result}`)

中级程序员的写法:

const Status={
    MASSAGE:0,
    SPA:1,
    DABAOJIAN:2
}
function getServe(status : number){
    if(status ===Status.MASSAGE){
        return 'massage'
    }else if(status ===Status.SPA){
        return 'SPA'
    }else if(status ===Status.DABAOJIAN){
        return 'dabaojian'
    }
}
const result=getServe(Status.SPA)
console.log(`我要去${result}`)

高级程序员的写法:

//因为枚举有个默认值,默认是从0,1,2,3这样的顺序
enum Status{
    MASSAGE,
    SPA,
    DABAOJIAN,
}
function getServe(status : number){
    if(status ===Status.MASSAGE){
        return 'massage'
    }else if(status ===Status.SPA){
        return 'SPA'
    }else if(status ===Status.DABAOJIAN){
        return 'dabaojian'
    }
}
const result=getServe(Status.SPA)
console.log(`我要去${result}`)

当然也可以修改默认值:
这样后面的数值也会按着顺序依次改

enum Status{
    MASSAGE = 1,
    SPA,
    DABAOJIAN,
}

9.泛型

9.1方法中的泛型的使用

需求1:前面是字符串,后面也要求传字符串
function join<jsPang>(first:jsPang,second:jsPang){
    return `${first}${second}`
}
//调用的时候指定类型
join<number>(1,2);

这里就在调用这个方法的时候定义参数类型,如果传入其他类型就会直接报错。

需求2:要求传入的参数是数组

params:ANY[]或者params:Array(ANY)都是可以的

function myFun<ANY>(params:ANY[]){
//function myFun<ANY>(params:Array(ANY)){
    return params;
}
myFun<string>(["123","3456"])

传入是数组还有一种写法:

需求3:多个泛型的定义

一般泛型用字母T表示

function join<T,P>(first:T,second:P){
    return `${first}${second}`
}
//调用的时候指定类型
join<string,number>('1',2);
需求4:泛型的继承

根据编号返回名字

class SelectGirl<T>{
    constructor(private girls: T[]){}
    getGirl(index :number):T{
        return this.girls[index]
    }
}
const selectGirl=new SelectGirl<string>(["大脚","刘颖","六月"])
console.log(selectGirl.getGirl(1))//"刘颖"

如果要求返回名字,就需要用单泛型的继承

interface Girl{
    name:string
}
//继承了Girl接口,就必须要有一个name属性
class SelectGirl<T extends Girl>{
    constructor(private girls: T[]){}
    getGirl(index :number):string{
        return this.girls[index].name
    }
}
const selectGirl=new SelectGirl([
    {name:"大脚"},
    {name:"刘颖"},
    {name:"六月"}
])
console.log(selectGirl.getGirl(1))//"刘颖"
需求5:泛型的约束

例如:在两个类型中选择一种,要么是number类型,要么是string类型

class SelectGirl<T extends number | string>{
    constructor(private girls: T[]){}
    getGirl(index :number):T{
        return this.girls[index]
    }
}
const selectGirl=new SelectGirl<string>(["大脚","刘颖","六月"])
console.log(selectGirl.getGirl(1))

10.ts的命名空间

10.1 搭环境

1.安装package.json
生成默认的文件

npm init -y

2.生成tsconfig.json

tsc -init

修改:

"outDir": "./build",                   
"rootDir": "./src", 

3.目录结构
在这里插入图片描述
在src里面随便写了个demo.ts
html里面的script的src指向build的demo.js

 <script src="./build/demo.js"></script>

浏览器打开html就可以看打印的内容,因为js在浏览器里面可以编译

10.2 感受命名空间的好处:减少不必要的全局变量

demo.ts:

class Header{
    constructor(){
        const elem =document.createElement('div')
        elem.innerText='This is Header';
        document.body.appendChild(elem)
    }
}
class Body{
    constructor(){
        const elem =document.createElement('div')
        elem.innerText='This is Body';
        document.body.appendChild(elem)
    }
}
class Footer{
    constructor(){
        const elem =document.createElement('div')
        elem.innerText='This is Footer';
        document.body.appendChild(elem)
    }
}
class Page{
    constructor(){
        new Header();
        new Body();
        new Footer();
    }
}

最后编译出来是这样的:
变量都是var定义的

"use strict";
var Header = /** @class */ (function () {
    function Header() {
        var elem = document.createElement('div');
        elem.innerText = 'This is Header';
        document.body.appendChild(elem);
    }
    return Header;
}());
var Body = /** @class */ (function () {
    function Body() {
        var elem = document.createElement('div');
        elem.innerText = 'This is Body';
        document.body.appendChild(elem);
    }
    return Body;
}());
var Footer = /** @class */ (function () {
    function Footer() {
        var elem = document.createElement('div');
        elem.innerText = 'This is Footer';
        document.body.appendChild(elem);
    }
    return Footer;
}());
var Page = /** @class */ (function () {
    function Page() {
        new Header();
        new Body();
        new Footer();
    }
    return Page;
}());

html里面调用这个js

<script>
        new Page() 
    </script>

在浏览器里面也可以直接打印这些全局变量
在这里插入图片描述
使用命名空间的写法:

只有Home.page被暴露出去了,剩下的都是Home的方法

namespace Home{

    class Header{
        constructor(){
            const elem =document.createElement('div')
            elem.innerText='This is Header';
            document.body.appendChild(elem)
        }
    }
    class Body{
        constructor(){
            const elem =document.createElement('div')
            elem.innerText='This is Body';
            document.body.appendChild(elem)
        }
    }
    class Footer{
        constructor(){
            const elem =document.createElement('div')
            elem.innerText='This is Footer';
            document.body.appendChild(elem)
        }
    }

export class Page{
    constructor(){
        new Header();
        new Body();
        new Footer();
    }
}
}

编译后这样:

"use strict";
var Home;
(function (Home) {
    var Header = /** @class */ (function () {
        function Header() {
            var elem = document.createElement('div');
            elem.innerText = 'This is Header';
            document.body.appendChild(elem);
        }
        return Header;
    }());
    var Body = /** @class */ (function () {
        function Body() {
            var elem = document.createElement('div');
            elem.innerText = 'This is Body';
            document.body.appendChild(elem);
        }
        return Body;
    }());
    var Footer = /** @class */ (function () {
        function Footer() {
            var elem = document.createElement('div');
            elem.innerText = 'This is Footer';
            document.body.appendChild(elem);
        }
        return Footer;
    }());
    var Page = /** @class */ (function () {
        function Page() {
            new Header();
            new Body();
            new Footer();
        }
        return Page;
    }());
    Home.Page = Page;
})(Home || (Home = {}));

html里面调用这个js,要改为命名空间下的Page

<script>
        new Page() 
    </script>

浏览器打印不出来Headers
在这里插入图片描述
而是Home下面只有Page
在这里插入图片描述

10.3真正项目中的使用

1)components.ts:单独模块的ts文件

namespace Components{
    export class Header{
        constructor(){
            const elem =document.createElement('div')
            elem.innerText='This is Header';
            document.body.appendChild(elem)
        }
    }
    export class Body{
        constructor(){
            const elem =document.createElement('div')
            elem.innerText='This is Body';
            document.body.appendChild(elem)
        }
    }
    export class Footer{
        constructor(){
            const elem =document.createElement('div')
            elem.innerText='This is Footer';
            document.body.appendChild(elem)
        }
    }
}

2)demo.ts:ts文件的出口

namespace Home{
    export class Page{
        constructor(){
            //Components命名空间下的方法
            new Components.Header();
            new Components.Body();
            new Components.Footer();
        }
    }
}

3)输入命令:tsc编译
4)demo.js文件这样:

"use strict";
var Home;
(function (Home) {
    var Page = /** @class */ (function () {
        function Page() {
            //Components命名空间下的方法
            new Components.Header();
            new Components.Body();
            new Components.Footer();
        }
        return Page;
    }());
    Home.Page = Page;
})(Home || (Home = {}));

5)html.js:
由于页面只引入了build/demo.js,而build/demo.js依赖于Components.js,所以会报错

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script src="./build/demo.js"></script>
    <script>
        new Home.Page() 
    </script>
</body>
</html>

在这里插入图片描述
6)针对这个情况可以在html页面引入Components.js,但比较麻烦。webpack编译一般指需要引入一个js文件,那怎么解决呢?
放开注释 -> 指明输出的文件:“outFile”: “./build/page.js”,
但这种情况下 module需要改成"amd"

	 "module": "amd",                          
     "outFile": "./build/page.js",                             /* Concatenate and emit output to single file. */
     "outDir": "./build",                              /* Redirect output structure to the directory. */
     "rootDir": "./src",   

7)html也改下js的路径:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script src="./build/page.js"></script>
    <script>
        new Home.Page() 
    </script>
</body>
</html>

10.4命名空间的嵌套

components.ts:

namespace Components{
    export namespace SubComponents{
        export class Test{
            
        }
    }
    export class Header{
        constructor(){
            const elem =document.createElement('div')
            elem.innerText='This is Header';
            document.body.appendChild(elem)
        }
    }
    export class Body{
        constructor(){
            const elem =document.createElement('div')
            elem.innerText='This is Body';
            document.body.appendChild(elem)
        }
    }
    export class Footer{
        constructor(){
            const elem =document.createElement('div')
            elem.innerText='This is Footer';
            document.body.appendChild(elem)
        }
    }
}

重新编译以后,浏览器可以打印:
在这里插入图片描述

10.5import语法

components.ts:


export class Header {
    constructor() {
        const elem = document.createElement('div')
        elem.innerText = 'This is Header';
        document.body.appendChild(elem)
    }
}
export class Body {
    constructor() {
        const elem = document.createElement('div')
        elem.innerText = 'This is Body';
        document.body.appendChild(elem)
    }
}
export class Footer {
    constructor() {
        const elem = document.createElement('div')
        elem.innerText = 'This is Footer';
        document.body.appendChild(elem)
    }
}

demo.ts:

import {Header,Body,Footer} from './components'
export default class Page {
    constructor() {
        //Components命名空间下的方法
        new Header();
        new Body();
        new Footer();
    }
}

编译后的page.js:
在这里插入图片描述

html:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.js"></script>
    <script src="./build/page.js"></script>
    <script>
        require(["demo"], function (demo) {
            new demo.default();
        });
    </script>
</body>

</html>

四.tyscript基础数据类型

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值