typescript点滴yan

typescript优点,缺点

优点:
1可以在编译阶段就发现大部分错误,这总比在运行时候出错好
2增强了编辑器和 IDE 的功能,包括代码补全、接口提示、跳转到定义、重构等
3TypeScript 非常包容,.js 文件可以直接重命名为 .ts 即可,即使不显式的定义类型,也能够自动做出类型推论,兼容第三方库.
4TypeScript 拥有活跃的社区.
缺点:
---有一定的学习成本,需要理解接口(Interfaces)、泛型(Generics)、类(Classes)、枚举类型(Enums)等前端工程师可能不是很熟悉的概念
---短期可能会增加一些开发成本,毕竟要多写一些类型的定义,不过对于一个需要长期维护的项目,TypeScript 能够减少其维护成本
---集成到构建流程需要一些工作量
----可能和一些库结合的不是很完美
typescript的基本类型

TypeScript学习(四)——变量类型约束(&,|,别名,数组,类型断言,枚举,元祖)

typescript深入

第四节:TypeScript 数组类型
typescript——(private、public、protected、static、abstract、readonly)
TypeScript 中枚举的用法

TypeScript声明文件

Typescript中的协变、逆变、双向协变

---协变,协变是指:子集能赋值给其超集。
class Chordate {
    hasSpine(): boolean {
        return true;
    }
}
class Mammal extends Chordate {
    canBreastFeed(): boolean {
        return true;
    }
}
function foo(animal: Chordate){
    animal.hasSpine();
}
foo(new Chordate());
foo(new Mammal());
---逆变
逆变(Contravariance)与双变(Bivariance)只针对函数有效。 --strictFunctionTypes 开启时只支持逆变,关闭时支持双变。
class Chordate {
    hasSpine(): boolean {
        return true;
    }
}
class Mammal extends Chordate {
    canBreastFeed(): boolean {
        return true;
    }
}
declare let f1: (x: Chordate) => void;
declare let f2: (x: Mammal) => void;
f2=f1;
f1=f2; //Error: Mammal is incompatible with Chordate
---双向协变
在老版本的 TS 中,函数参数是双向协变的。也就是说,既可以协变又可以逆变,但是这并不是类型安全的。在新版本 TS (2.6+) 中 ,你可以通过开启 strictFunctionTypes 或 strict 来修复这个问题。设置之后,函数参数就不再是双向协变的了。
type 与 interface 的区别
1. interface仅可以用来定义function, type,interface。而type还可以定义其他number string []等基础类型。
2. interface可以重复定义一个A类型,并且会合并, type不行。
3. interface可以继承interface,继承type,使用extends关键字,type也可继承type,也可继承interface,继承只能使用&。还有类可以实现接口,也可以实现type。
4. interface可以遍历属性名,或者引用
interface和class区别

interface:
1-接口的可选属性
2-函数类型接口
3-可索引接口
类(class):
1.类的静态属性和静态方法
2.抽象方法抽象类
3.多态:父类定义一个基础方法,让继承的每个子类实现不同的功能
4.类含有构造器函数,可以做一些初始化操作。
5.类可以保存状态。
6.类可以做一些ioc控制反转。

泛型

泛型在 TS 中可以说是一个非常重要的属性,它承载了从静态定义到动态调用的桥梁,同时也是 TS 对自己类型定义的元编程。

写TS效率大提升,TypeScript中常用内置工具类型Omit、Pick、Partial、Required、Readonly、Exclude 、Extract

如何编写 TypeScript 声明文件

index.d.ts 全局声明
@types/xxx 
/// 引入: 比如 /// <reference types="react" />
自己写的包写好ts文件
type拓展
type Name = { name: string };
interface IName { name: string };
----
type Person = Name & { age: number };
interface IPerson extends IName { age: number }

泛型常用运算符

-------
type Pick<T, K extends keyof T> = {
    [key in K]: T[key];
}
-------
type Partial<T> = {
  [P in keyof T]?: T[P]
}
-------
type Required<T> = {
    [key in keyof T]-?: T[P]
}
-------
// Exclude就是判断 T 是否继承于 U,如果是,则返回 never,否则返回 T含有U不含有的。(联合类型是提取T提取不同的,而类也是提取不同的,类我亲自测试的是返回T而不是提取不同的, 有的文章说这里返回T所哟逇其实并不严谨)
// 集合的时候后边是前边的子集,返回前有,后没有
type Exclude<T, U> = T extends U ? never : T;
// Extract 的功能,与 Exclude 相反,它是 提取 T 中可以赋值给 U 的类型(联合类型是T提取相同,而class是全部)。
// 集合的时候后边是前边的子集,返回后边的
-------
type Extract<T, U> = T extends U ? T : never
-------
type Omit = Pick<T, Exclude<keyof T, K>>;
-------
type ReturnType<T extends func> = T extends () => infer R ? R: any;
function getUser() {
  return {name: 'xxx', age: 10}
}
type GetUserType = typeof getUser;
type ReturnUser = ReturnType<GetUserType>
-------
Record
interface PageInfo {
  title: string;
}
type Page = "home" | "about" | "contact";
const nav: Record<Page, PageInfo> = {
  home: { title: "home" },
  about: { title: "about" },
  contact: { title: "contact" },
};
type Record<K extends string | number | symbol, T> = {
    [P in K]: T;
}
{} 任何不为空的对象
--- 联合类型 Exclude使用
type Fruits = "apple" | "banana" | 'peach' | 'orange';
type DislikeFruits = "apple" | "banana";
type FloveFruits = Exclude<Fruits, DislikeFruits> // 等效于 type FloveFruits = "peach" | "orange"
---联合类型 Extract
type Fruits = "apple" | "banana"  | 'peach' | 'orange';
type DislikeFruits = "apple" | "banana";
type FloveFruits = Extract<Fruits, DislikeFruits> // 等效于 type FloveFruits = "apple" | "banana"
--- class Extract和Exclude
interface IPerson {
  name: string,
  age: number,
  sex: boolean,
}
interface IMan {
  name: string,
  age: number,
}
继承关系
type Man = Exclude<IPerson, IMan> // 等效于 type Man = never
type Man = Extract<IPerson, IMan> // 等效于 type Man = IPerson
非继承关系
type Man = Exclude<IMan, IPerson> // 等效于 type Man = {}
type Man = Extract<IMan, IPerson> // 等效于 type Man = never;
------
interface IPerson {
  name: string,
  age: number,
  sex: boolean,
}
interface IMan {
  name: string,
  age: number,
  side: number;
}
非继承关系
type Man = Exclude<IMan, IPerson> // 等效于 type Man = {sex: boolean}
type Man = Extract<IMan, IPerson> // 等效于 type Man = never;


ts类型声明文件的正确使用姿势
typeScript第三篇tsconfig.json配置文件、namespace命名空间、三斜线指令、声明文件d.ts、Mixins混入、装饰器Decorator、Rollup、webpack构建TS

ts中引入 js的理论与实践
useMemo,useCallback
TypeScript 基础类型 —— Null 和 Undefined

declare是干嘛的

ts的.d.ts和declare究竟是干嘛用的
.d.ts 文件中的顶级声明必须以 “declare” 或 “export” 修饰符开头。
通过declare声明的类型或者变量或者模块,在include包含的文件范围内,都可以直接引用而不用去import或者import type相应的变量或者类型。

1.declare声明一个类型

declare type Asd {
    name: string;
}

在include包含的文件范围内可以直接使用Asd这个type

2.declare声明一个模块

最经典的声明模块应该是这样了

declare module '*.css';
declare module '*.less';
declare module '*.png';

在编辑ts文件的时候,如果你想导入一个.css/.less/.png格式的文件,如果没有经过declare的话是会提示语法错误的

3.declare声明一个变量

这个什么情况下会用到呢?假如我在项目中引入了一个sdk,这个sdk(我们以微信的sdk为例)里面有一些全局的对象(比如wx),但是如果不经过任何的声明,在ts文件里面直接用wx.config()的话,肯定会报错。
有一句说法我蛮喜欢的:declare就是告诉TS编译器你担保这些变量和模块存在,并声明了相应类型,编译的时候不需要提示错误!

4. declare声明一个作用域

declare namespace API {
    interface ResponseList {}
}

声明完之后在其他地方的ts就可以直接API.ResponseList引用到这个接口类型

注意:

1…d.ts文件顶级声明declare最好不要跟export同级使用,不然在其他ts引用这个.d.ts的内容的时候,就需要手动import导入了

2.在.d.ts文件里如果顶级声明不用export的话,declare和直接写type、interface效果是一样的,在其他地方都可以直接引用

declare type Ass = {
    a: string;
}
type Bss = {
    b: string;
};

自定义组件渲染

import React from 'react';
import ReactDOM from 'react-dom';
let root: HTMLElement | null = document.getElementById('root');
interface Props {
    name: string;
}
function Welcome(props: Props): React.ReactElement {
    return <h1>Hello, {props.name}</h1>;
}
class Welcome2 extends React.Component<Props> {
    render(): React.ReactElement {
        return <h1>Hello, {this.props.name}</h1>;
    }
}

const element1: React.ReactElement<Props, React.JSXElementConstructor<Props>> = <Welcome name="zhufeng" />;
console.log(element1.props.name);
const element2: React.ReactElement<Props, React.JSXElementConstructor<Props>> = <Welcome2 name="zhufeng" />;
console.log(element1.props.name);

ReactDOM.render(
    <div>{element1}{element2}</div>,
    root
);

接上边的问题,那么如果定义一个html元素如何理解

let root: HTMLElement | null = document.getElementById('root');//这个是dom元素对象
let root: React.ReactElement  | null = <div>ttttttt</div> // 这个当jsx,会转化为react元素
React.FC 等于 React.FunctionComponent
const App: React.FC<{ message: string }> = ({ message }) => (
  <div>{message}</div>
);

三斜线指令

/// <reference path="./node.d.ts" />
/// <reference types="node" />

path 类型声明的是对本地文件的依赖,包含路径信息。
types 类型声明的是对 node_modules/@types 文件夹下的类型的依赖,不包含路径信息。

TypeScript基础入门之三重斜线指令

ts 忽略类型检查

单行忽略(添加到特定行的行前来忽略这一行的错误)

// @ts-ignore

跳过对某些文件的检查 (添加到该文件的首行才起作用)

// @ts-nocheck

对某些文件的检查

// @ts-check

禁用 ESLint 语法校验的方法

如何针对单个 js 文件禁用 ESLint 语法校验,但整个项目依然保留 ESLint 的校验规则?

/* eslint-disable */

还可以在注释后加入详细规则,这样就能避开指定的校验规则了

/* eslint-disable no-new */

typescript定义函数的方式

TypeScript——函数(函数定义类型、可选参数和默认参数、剩余参数、函数类型变量、使用接口封装函数变量类型)

小众需求

promise不能中断

在这里插入图片描述

as const

infer
博客1
博客2

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值