1.ts 静态类型
就是定义数据类型后,不可改变,还有深层级的理解,就是继承定义变量的属性及方法。
基础静态类型 冒号后跟数据类型 可以跟 number string null undefinde boolean void
const guan:{
name:string,
age:number
} = {
name:'关关',
age:19
}
const guan2 :string [] = ['谢大脚','刘英'] // 定义数组类型,里面是字符串类型
class Preson{}
const guan3 :Preson = new Preson()
const guan4 :()=>string = ()=>{return '广告'} 2.ts 类型注解和类型推断类型注解
let count : number cont = 123 // 鼠标放上 会有提示 nmuber 类型类型注解
const one = 1 const two = 2 const three = one + two // 鼠标放上 自动推断出 three 是 number 类型
function getTotal(one,two) {
return one + two
}
const total = getTotal(1,2) // 这时鼠标放到 total 上 显示 any 则推断不出来返回是什么类型
function getTotal(one:number,two:number) {
return one + two
}
const total = getTotal(1,2) //这时鼠标放到 total 上 显示number 可以判断出 对象中常量的类型 const guan5 = {
name:'guanguan',
age:18
} // 鼠标放到 Guana5 上会显示 name : string age:number 3.初识 interface因为 interface 这个概念在js中并没有,所以 interface 编译后并不会呈现到 js 中,只会进行静态的类型检查。
// 没用之前
const getFn = (name:string,age:number,bust:number)=>{
console.log('姓名:', name);
}
getFn('12',2,2)
// 用interface
interface Girl {
name:string;
age:number;
bust:number
}
const girl = {
name:'关关',
age:12,
bust:90
}
const getFn = (girl:Girl)=>{
console.log('姓名:', girl.name);
}
getFn(girl) 会发现相同得传值地方很多,需要每次去写,不优雅,代码繁琐。你就会问和 类型别名 type ,其实是一样得就一点 不同,type 是直接可以赋值得,但是 interface 传递就必须是一个对象。
type Girl1 = string
想要传递更多参数,但是又不是必填字段,该怎么写?在后面添加一个问号interface Girl {
name:string;
age:number;
bust:number;
like?:string;
}
const girl = {
name:'关关',
age:12,
bust:90,
like:'帅哥'
}
const getFn = (girl:Girl)=>{
console.log('喜欢:',girl.like);
}
getFn(girl) 如果 like 后面没有跟 ?console.log(girl.like) 报错了。
这个时候你又应该问了,几个参数还可以写,要是很多参数怎么办,总不能一个一个写吧 ,哈哈。ts 也帮我们解决了,如下 [propname:string] 代表属性名是字符串类型,他得值是 any 任何类型。
interface Girl {
name:string;
age:number;
bust:number;
like?:string;
[propname:string]:any
}
const girl = {
name:'关关',
age:12,
bust:90,
like:'帅哥',
sex: '女',
eat:'苹果'
}
const getFn = (girl:Girl)=>{
console.log('喜欢:',girl);
}
getFn(girl)
给 Girl 添加一个说话得方法interface Girl {
name:string;
age:number;
bust:number;
like?:string;
[propname:string]:any;
say():string
}
const girl = {
name:'关关',
age:12,
bust:90,
like:'帅哥',
sex: '女',
eat:'苹果',
say:(()=>{return '123'})
}
const getFn = (girl:Girl)=>{
console.log('喜欢:',girl.say());
}
getFn(girl) extends与implements的不同1.在类得声明中,通过关键字 extends 来创建一个类得子类。一个类通过 implements 声明自己使用一个或者多个接口。
2.extends 是继承某个类,继承之后可以使用父类得方法,也可以重写父类得方法。
interface Girl {
name: string;
age: number;
bust: number;
like?: string;
[propname: string]: any;
say(): string
}
interface Teacher extends Girl {
teach(): string
}
class Preson implements Girl {
name = '111'
age = 12
bust = 90
say() {
return '欢迎光临'
}
}
const girl = {
name: '关关',
age: 12,
bust: 90,
like: '帅哥',
sex: '女',
eat: '苹果',
say: (() => { return '123' }),
teach: (() => {
return 'jdijisodsids'
})
}
const getFn = (girl: Teacher) => {
console.log('喜欢:', girl.teach());
}
getFn(girl) 4.类的使用class Lady {
content = 'hi 你好啊'
sayHello() {
return this.content
}
}
class Gril extends Lady{
content = "不开心",
sayHello() {
return super.sayHello() + '111' // 使用父类中sayHello 方法
}
}
let LadyClass = new Gril()
console.log(LadyClass.sayHello()); // 不开心
console.log(LadyClass.content); // 不开心 5.类的访问private 私有的 不能在外部及继承中使用,代码提示会报错,无法使用
protected 保护的 能在内部使用,不能在外部使用 但是在继承中是可以使用的
pulbic 公有的 在内部和外部都是可以调用的
类的内部和外部 {}外是外部 {}内是内部
class Person {
public name: string | undefined;
protected say(){
console.log(this.name + '你好啊');
return this.name + '你好啊'
}
}
const person = new Person()
person.name = 'jsGuan'
person.say()
console.log(person.say()); name 如果不写就是默认为 public 所以在内部,外部是能访问的 person.name x现在把 say 方法写 protected 就会发现在外部是调用 say 方法是有访问不到的。6.类的构造函数
class Person {
public name : string | undefined
constructor(name:string){
this.name = name
}
}
const person = new Person('guanguan')
console.log(person.name); // guanguan
// 简便写法
class Person {
constructor( public name:string){
}
}
// 继承 子类只有是构造函数 constructor 就必须调用super() 方法
class Person {
constructor( public name:string){
}
}
class Son extends Person{
constructor(public age:number) {
super('jingjing')
}
}
const son = new Son(12)
console.log(son.name); // jingjing
console.log(son.age); //12 7.类的Getter setter static class xiaoJieJie {
constructor(private _age:number){ }
get age () {
return this._age
}
}
const mom = new xiaoJieJie(18)
console.log(mom.age); 比如小姐姐类的年龄,不想让外界知道,所以 用 private 保护起来,通过 get 方式 renturn 出去。可以在 get 方法里面做一些操作封装一下等等。先执行 set 在执行 get class xiaoJieJie {
constructor(private _age:number){ }
get age () {
console.log(2);
return this._age + 1
}
set age (age:number) {
console.log(1);
this._age = age + 10
}
}
const mom = new xiaoJieJie(18)
mom.age = 20
console.log(mom.age); // 31 补充一个 静态类的方法
不需要在实例化 一个对象 进行调用,直接用 class.方法属性
class Girl {
static sayLove() {
return 'I love you'
}
}
console.log(Girl.sayLove()); 只读属性 readonly class Person {
public readonly _name :string
constructor(name:string) {
this._name = name
}
}
const person = new Person('guanguan')
person._name = 'jingjing' // 报错 因为 _name 属性是只读属性
console.log(person._name); 8.抽象类
概念:和父类很像都需要继承,抽象类一般都有一个抽象方法,继承抽象类的类,必须实现抽象方法才可以
关键字 abstract// 每一个类都需要一个技能 但是 每一个类里面 他们的技能是不同的 可以用抽象类
abstract class Girl {
abstract skill():any // 没有大括号,因为每一个类的方法是不同的,所以不同写上
abstract say() :any
}
class waiter extends Girl {
skill() {
// 实际操作逻辑
console.log(1);
}
say() {
console.log(2);
}
}
class Baseteacher extends Girl {
skill() {
console.log(3);
}
say() {
console.log(4);
}
} 9.联合类型和类型保护(也叫类型守护)只有参数有或者有2种以上这种方法就叫做联合类型
interface son {
anjiao:boolean;
say: ()=>{
la:string
age:number
}
}
interface teacher {
anjiao:boolean;
sayBey: ()=>{
la:string
age:number
}
}
function whatHow(animal:son | teacher) {
} animal.say() 发现会报错。因为你不知道这个 say() 方法是谁的,所以这个时候就会用到类型守护。
2.in 方式
3.typeof
4.instanceof
interface son {
anjiao:boolean;
}
interface teacher {
anjiao:boolean;
sayBay: (()=>{})
}
function whatHow(animal:son | teacher) {
if (animal.anjiao) {
(animal as son).anjiao
console.log(animal.anjiao);
} else {
(animal as teacher).sayBay()
console.log( (animal as teacher).sayBay()); // 'wowowo'
}
}
const Girl = {
anjiao:false,
sayBay(){
return 'wowowo'
}
}
whatHow(Girl) in 方式 ('skill' in type)interface son {
anjiao:boolean;
skill :(()=>{})
}
interface teacher {
anjiao:boolean;
sayBay: (()=>{})
}
const Girl = {
anjiao:false,
sayBay(){
return 'wo shi saybay'
}
}
function towho(type:son | teacher) {
if ('skill' in type) {
type.skill()
console.log( type.skill());
} else {
type.sayBay()
console.log( type.sayBay()); // 'wo shi saybay'
}
}
towho(Girl) function add(frist: number | string, second: number | string) {
if (typeof frist === "string" || typeof second === "string") {
return `${frist}${second}`
}
return frist + second
} 10.tyepscript 命名空间 namespace1.新建一个文件夹 放到 vscode 中 ,然后打开终端,允许 npm init -y 创建 package.json 文件。
2.生成文件后,我们直接在终端允许 tsc -init ,生成 tsconfig.json
3.新建 src 和 build 文件夹,在创建一个 index.html
4.在 src 目录下,新建 一个 page.ts 文件,开始要编写 ts 文件了。
5.在配置 tsconfig.json 文件,设置 outDir 和 rootDir, 也就是设置需要编译的文件目录,和编译好的文件目录。
6.然后编写 index.html,引入,当让我们现在还没有 page.js 文件
7.编写page.ts文件,加入一句输出console.log('你好 关关'),再在控制台输入tsc,就会生成page.js文件
8.再到浏览器中查看 index.html 文件,如果按F12可以看到你好 关关,说明我们的搭建正常了。
看到上面还是没有使用命名空间时,Top Contrnt Footer 都是全局变量,容易造成全局变量混乱,所以需要进行模块化的划分,这个时候就需要 进行命名空间,关键字时 namespace 写法在 page.ts 中注释那样进行编写。
这个语法,很类似编程中常说的模块化思想,比如webpack打包时,每个模块有自己的环境,不会污染其他模块,不会有全局变量产生。命名空间就跟这个很类似,注意这里是类似,而不是相同。
命名空间声明的关键词是namespace比如声明一个namespace Home,需要暴露出去的类,可以使用export关键词,这样只有暴漏出去的类是全局的,其他的不会再生成全局污染了
index.html script 修改
new Home.Page();深入了解 命名空间,接近实战,命名空间组件化

京公网安备 11010502036488号