联合类型和类型保护
interface Bird {
fly: boolean;
sing: () => {}
}
interface Dog {
fly: boolean;
bark: () => {}
}
// 类型断言的方式
function demo(animal: Bird | Dog) {
if(animal.fly){
(animal as Bird).sing()
}else {
(animal as Dog).bark()
}
}
// in 语法来做类型保护
function demo1(animal: Bird | Dog) {
if("sing" in animal) {
animal.sing()
}else {
animal.bark()
}
}
// typeof 语法来做类型保护
function add(first: string | number, second: string | number) {
if(typeof first === "string" || typeof second === "string") {
return `${first}${second}`
}
return first + second
}
// 使用 instanceof 语法来做类型保护
// 只有类才具有instanceof ,不能用interface
// instanceof 用于判断一个变量是否某个对象的实例
class NumberObj {
count: number
}
function add(first: object | NumberObj, second: object | NumberObj) {
if(first instanceof NumberObj && second instanceof NumberObj) {
return first.count + second.count
}
return 0
}
枚举类型 Enum
- npm install typescript --save
- npm install ts-node -D
package.json
"scripts": {
"dev": "ts-node ./demo.ts"
}
// 枚举
enum Status {
OFFLINE, // 0
ONLINE = 3, // 3
DELETED // 4
}
赋值是按顺序,默认0开始
Status[0] = OFFLINE
Status[3] = ONLINE
Status[4] = DELETED
函数泛型 , 泛指的类型
function join<ABC>(first:ABC, second:ABC) {
return `${first}`
}
join<number>(1, 1)
function join<T, P>(first:T, second:P) {
return `${first}${second}`
}
join<number, string>(1, "100")
join(1, "100") // 也可以这样,不写具体类型与泛型匹配,他会自己推断
类中的泛型以及泛型类型
interface Item {
name: string
}
class DataManager<T extends Item>{
constructor(private data: T[]) {}
getItem(index: number): string {
return this.data[index].name;
}
}
const data = new DataManager([{name: "jack"}])
class DataManager<T extends number | string>{
constructor(private data: T[]) {}
getItem(index: number): T {
return this.data[index];
}
}
const data = new DataManager<number>([])
// 如何使用泛型作为一个具体的类型注解
function hello<T>(params: T){ return params }
const func: <T>(params: T) => <T> = hello;
命名空间
- tsc -w 这命令是监听 .ts 文件,每次.ts文件有变动的时候,自动编译
你把所有东西放到Home这个命名空间里面,
有些东西不想暴露出去,只想暴露出去某些东西,Page就不能直接拿了
namespace Home {
class Header {…… ……}
class Content {…… ……}
class Footer {^ ^}
export class Page {
new Header()
new Content()
new Footer()
}
}
// 命名空间也可以套命名空间,里面也可以写interface
namespace Components {
export namespace SubComponent {
export class Test {}
}
export interface User {
name: string
}
}
使用parcel打包TS代码,这个编译器会分析如果html引入.ts文件,它会自动帮我们把.ts编译,然后编译成浏览器可以运行的代码, 把这个.ts文件会生成一个.js文件
- npm install parcel@next -D
<html>
<script src="./page.ts"></script>
</html>
在package.json 里使用
{
"scripts": {
"test": "parcel ./src/index.html"
}
}
描述文件中的全局类型
- 新建 jquery.d.ts文件【类型描述文件】帮助我们去理解对应的 .js 文件
declare:解释或者描述一个全局变量
declare var $: (param: () => void) => void;
定义全局函数
interface JqueryInstance {
html: (html:string) => JqueryInstance
}
declare function $(readyFunc: () => void): void;
declare function $(selector:string): JqueryInstance;
// 如何对对象进行类型定义,以及对类进行类型定义,以及命名空间的嵌套
declare namespace $ {
namespace fn {
class init{}
}
}
// 使用 interface 的语法,实现函数重载
interface JQuery {
(readyFunc: () => void): void;
(selector:string): JqueryInstance;
}
declare var $: JQuery;
模块代码的类型描述文件
由于 install jquery 并没有ts的描述文件,我们要手动描述
import $ from "jquery";
$(function (){
$("body").html("<div>111</div>")
$.fn.init()
})
// ES6模块化
declare module "jquery" {
interface JqueryInstance {
html: (html:string) => JqueryInstance
}
// 混合类型
function $(readyFunc: () => void): void;
function $(selector:string): JqueryInstance;
namespace $ {
namespace fn {
class init{}
}
}
export = $;
}
泛型中 keyof 语法的使用
要有类型保护
const name = teacher.getInfo("name") as string // 返回的是string类型
interface Person {
name: string;
age: number;
gender: string;
}
class Teacher {
constructor(private info: Person) {}
getInfo<T extends keyof Person>(key: T): Person[T] {
return this.info[T]
}
}
const teacher = new Teacher({
name: 'jack',
age: 25,
gender: 'male'
})
const test = teacher.getInfo("name")
结语
前端react QQ群:
788023830----React/Redux - 地下老英雄前端交流 QQ群:
249620372----FRONT-END-JS前端(我们的宗旨是,为了加班,为了秃顶……,仰望大佬),希望小伙伴们加群一起学习