- 一、基础
- 二、进阶
- 全局变量处理
- type和interface的区别
- as
- 单行禁用ts
- Pick
, 将T类型中的K属性挑出来 - Omit
, 将T类型中的K属性排除 - Partial
, 将T类型中的属性都变成可选属性。 - Required
, 将T类型中的属性都变成必选属性 - Extract
, 从类型T中提取所有可以赋值给U的类型,然后构造一个类型 +
-
这两个关键字用于映射类型中给属性添加修饰符,比如-?
就代表将可选属性变为必选,-readonly
代表将只读属性变为非只读.- https://mp.weixin.qq.com/s/LlMrYBcvs51-0CSz4pSWDw">学习地址:https://mp.weixin.qq.com/s/LlMrYBcvs51-0CSz4pSWDw
- any和unknow的区别
- undefinde和null的区别
- 在namespace里面使用
- 三、相关学习资料
一、基础
数据类型
布尔类型(boolean)、数字类型(number)、字符串类型(string)、数组类型(array)、元组类型(tuple)、枚举类型(enum)、object类型
任意类型(any)、null 和 undefined、void类型、never类型
HTMLDivElement、HTMLCanvasElement、HTMLSpanElement、HTMLAudioElement、Component
/**
* 数据类型
* boolean 布尔型
* number 数字型
* 元组类型(tuple)
* 枚举 enum
*/
let isMarried:boolean = true;
let age:number = 10;
let firstname:string = '张';
let hobbies:string[] = ['smoking','drinking','haire'];
let numbers:Array<number> = [4,5,6];
let students:Array<object> = [{name:'zfpx1'},{name:'zfpx2'}];
let fullname:[string,string,number] = ['张','三',9];
let arr2:Array<string|number|boolean> = ['hello',9,true];
let arr3:Array<any> = ['hello',9,true];
var num:number | undefined;
object类型:用来描述一种非基础类型,所以一般用在类型校验上,比如作为参数类型
declare function create(o: object | null): void;
create({ prop: 0 }); // 正确
create(null); // 正确
create(42); // 错误
create("string"); // 错误
create(false); // 错误
create(undefined); // 错误
枚举
enum 枚举名{
标识符[=整型常数],
标识符[=整型常数],
...
标识符[=整型常数],
} ;
//定义了一个枚举类型的值 性别 ,里面有两个选项 GIRL BOY
enum Gender{
GIRL='女生',//女孩0
BOY='男生'//男孩1
}
console.log(`李雷是${Gender.BOY},梅梅是${Gender.GIRL}`);
//去拼多多买货
enum OrderStatus{
WaitForPay='等待付款',
WaitForSend='等待发货',
Sended="已发货",
Signed='已签收'
}
// 如果标识符没有赋值 它的值就是下标
为那些在编程阶段还不清楚类型的变量指定一个类型any
//any 任何类型 任何值 放弃了检查
let root = document.getElementById('root');
root!.style!.color = 'red';
// a的类型可以改变
let a:any = 1;
a = 'zfpx';
// 不知道数组的数据结构
let list: any[] = [1, true, "free"];
list[1] = 100;
一个变量多种类型
// null undefined
let x:number|null|undefined;
x = 10;
x = undefined;
x = null;
let y:number;
//console.log(y);
没有任何类型void, 永不存在的值的类型never
void类型像是与any类型相反,它表示没有任何类型。当一个函数没有返回值时,你通常会见到其返回值类型是 void
never类型表示的是那些永不存在的值的类型。它是其他类型 (包括 null 和 undefined)的子类型,代表从不会出现的值。这意味着声明never的变量只能被never类型所赋值。
function greeting5(name:any):void{
console.log('hello',name);
return name
}
greeting5('zfpx');
let xxx:never;
xxx = (()=>{
throw new Error('Wrong')
})();
let yy:object = {name:'zfpx2'};
console.log(yy);
void和never和any区别
/**
* any 任何的值
* void 是any的反面,不能有任何值
* never 永远不会有返回值
*/
let ak:any = 10;
function say():void{}
//这个函数一旦开始执行,就永远结束的时候,就进入 死循环
function sum():never{
while(true){
console.log(1);
}
}
function multi():never{
throw Error('ok');
let a = 10;
let b =10;
}
function divide(a:number,b:number):never|number{
return a/b;
}
divide(10,2);
divide(10,0);
函数剩余参数和是否可传的参数
function greeting(name:string):void{
console.log('hello',name)
}
greeting('zfpx');
//ts 形参和实参要完全一样
function greeting2(name:string,age?:number):void{
console.log('hello',name,age)
}
greeting2('zfpx2');
// 赋初始值
function ajax(url:string,method:string='GET'){
console.log(method,url);
}
ajax('/user');
//剩余参数
function sum(...numbers:number[]){
return numbers.reduce((val,item)=>{
return val+item;
},0);
}
let ret = sum(1,2,3,4,5);
console.log(ret);
函数重载
/**
* 函数的重载
* Java里面呢重载 是指两个或两个以上的函数,参数的个数和类型不一样
* TS中的函数重载
*/
//函数的声明 只是用来限制参数的个数和类型
/* function attr(val:string):void;
function attr(val:number):void;
function attr(val:boolean):void; */
function attr(val:string|number|boolean):void{
if(typeof val =='string'){
}else if(typeof val =='number'){
}else if(typeof val =='boolean'){
}
}
attr('zfpx');
attr(10);
attr({});
function parse(str:string):any|never{
return JSON.parse(str);
}
let obj = parse('{"name":"zfpx"');
console.log(obj);
function multi(a:number,b:number):void{
return 1;
}
class里面
// public 公开的,自己 子类 其它类都能访问
// protected 受保护的 自己 子类能访问 但是其它人不能访问
// private 私有的 只有自己访问,子类 其它人不能访问
// 属性如果不加修饰符 默认就是 公有 (public)
class Student extends Parent{
public name:string
protected age:number
private money:number
constructor(name:string,age:number,money:number){
super(name, age);//调用父类的构造函数
this.money = money;
}
getMoney(): string{
return this.money;
}
//静态属性
static myname='hello'
//加上static表示这个属性是静态的属性,是属于类的属性,可以通过类名来调用
static getName(){
// 这里面不能访问this,因为this指向Student的实例
}
}
interface Animal{
name:string;
eat(str:string):void;
}
class Dog implements Animal{
name:string;
constructor(name:string){
this.name=name;
}
eat(){
console.log(this.name+'吃粮食')
}
}
抽象类
定义:抽象类是可以从中派生其他类的基类。它们可能无法直接实例化。
描述:抽象方法必须包含abstract关键字
区别:抽象类中标记为抽象的方法不包含实现,必须在派生类中实现。
示例说明:抽象类Animal3,抽象方法speak是在Cat3中定义的。Animal3不能有实例,Cat3的实例不能访问speak2方法,可以访问speak方法。
abstract class Animal3{
public abstract speak():void;
}
class Cat3 extends Animal3{
speak(){
console.log('小猫喵喵喵!');
}
speak2(){
console.log('小猫喵喵喵!');
}
}
interface接口
接口的作用:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用。接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法,提供这些方法的类就可以满足实际需要。 typescrip中的接口类似于java,同时还增加了更灵活的接口类型,包括属性、函数、可索引和类等。
/**
* 接口 本质上是一种约束
* 约束对象
*/
interface userInterface{
home?:string,
height?:number,
name:string,
age:number
}
function getUserInfo(user:userInterface):void{
console.log(`${user.name} ${user.age} ${user.home}`)
}
function getVipInfo(user:userInterface):void{
console.log(`${user.name} ${user.age}`)
}
getUserInfo({name:'zfpx',age:10,home:'beijing'});
getVipInfo({name:'zfpx',age:10});
通过 keyof
拿到interface对象 key 的类型
interface Person {
name: string
age: number
}
type K1 = keyof Person // "name" | "age"
const str2: K1 = 'name'
对函数的参数和返回值进行约束
//如果希望对一个函数的参数和返回值 进行约束
interface discount{
(price:number):number
}
let cost:discount = function(price:number):number{
return price*.8;
}
console.log(cost(100));
泛型
//generic type
function calculate<T>(value:T):T{
return value;
}
//console.log(calculate<string>('zfpx'))
//console.log(calculate<number>(1));
//类的泛型 如何使用
class MyArray<T>{
private list:T[] = [];//定义一个私有的属性list
add(value:T){
this.list.push(value);
}
max():T{
let ret = this.list[0];
for(let i=1;i<this.list.length;i++){
if(this.list[i]>ret){
ret = this.list[i];
}
}
return ret;
}
}
let arr = new MyArray<string>();
arr.add('1');
arr.add('2');
arr.add('3');
console.log(arr.max());
二、进阶
全局变量处理
declare global {
namespace util {
export let connect: string
export function date(ms: number | string, fmt: string, countdown?: Boolean): string
export function gotoUrl(url: string):void
}
type和interface的区别
// 1继承的方式不同
interface Name {
name: string;
}
interface User extends Name {
age: number;
}
type Name = {
name: string;
}
type User = Name & { age: number };
// 泛型(Generics)是对共性的提取(不仅仅是描述)
// 接口是一种方面(Aspect)描述
as
interface Doo {
bar: number;
bas: string;
}
var foo = {} as Doo;
foo = {
bas: '23',
bar: 23
}
单行禁用ts
// tslint:disable-line
Pick, 将T类型中的K属性挑出来
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick<Todo, 'title' | 'completed'>;
const todo: TodoPreview = {
title: 'Clean room',
completed: false,
};
Omit, 将T类型中的K属性排除
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Omit<Todo, 'description'>;
const todo: TodoPreview = {
title: 'Clean room',
completed: false,
};
Partial, 将T类型中的属性都变成可选属性。
interface Todo {
title: string;
description: string;
}
function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
return { ...todo, ...fieldsToUpdate };
}
const todo1 = {
title: 'organize desk',
description: 'clear clutter',
};
const todo2 = updateTodo(todo1, {
description: 'throw out trash',
});
Required, 将T类型中的属性都变成必选属性
interface Props {
a?: number;
b?: string;
};
const obj: Props = { a: 5 }; // OK
const obj2: Required<Props> = { a: 5 }; // Error: property 'b' missing
Extract, 从类型T中提取所有可以赋值给U的类型,然后构造一个类型
type T0 = Extract<"a" | "b" | "c", "a" | "f">; // "a"
type T1 = Extract<string | number | (() => void), Function>; // () => void
Exclude
type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
type T1 = Exclude<"a" | "b" | "c", "a" | "b">; // "c"
type T2 = Exclude<string | number | (() => void), Function>; // string | number
+
-
这两个关键字用于映射类型中给属性添加修饰符,比如-?
就代表将可选属性变为必选,-readonly
代表将只读属性变为非只读.
type Required<T> = { [P in keyof T]-?: T[P] };
学习地址:https://mp.weixin.qq.com/s/LlMrYBcvs51-0CSz4pSWDw
export type PickByValueType<T, ValueType> = Pick<
T,
{ [Key in keyof T]-?: T[Key] extends ValueType ? Key : never }[keyof T]
>;
export type OmitByValueType<T, ValueType> = Pick<
T,
{ [Key in keyof T]-?: T[Key] extends ValueType ? never : Key }[keyof T]
>;
export type RequiredKeys<T> = {
[K in keyof T]-?: {} extends Pick<T, K> ? never : K;
}[keyof T];
export type OptionalKeys<T> = {
[K in keyof T]-?: {} extends Pick<T, K> ? K : never;
}[keyof T];
export type FunctTypeKeys<T extends object> = {
[K in keyof T]-?: T[K] extends Function ? K : never;
}[keyof T];
export type DeepRequired<T> = {
[P in keyof T]-?: T[P] extends object | undefined ? DeepRequired<T[P]> : T[P];
};
export type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
type Naked<T> = T extends boolean ? "Y" : "N";
type Wrapped<T> = [T] extends [boolean] ? "Y" : "N";
// "N" | "Y"
type Distributed = Naked<number | boolean>;
type TypeName<T> = T extends string
? "string"
: T extends number
? "number"
: T extends boolean
? "boolean"
: T extends undefined
? "undefined"
: T extends Function
? "function"
: "object";
// 使用上面的TypeName类型别名
// "string" | "function"
type T1 = TypeName<string | (() => void)>;
// "string" | "object"
type T2 = TypeName<string | string[]>;
// "object"
type T3 = TypeName<string[] | number[]>;
any和unknow的区别
相同的是 unknown 和 any 都可接收任意值,不同的是 unknown 的值必须 type check 或 type assertion 后才可使用,否则报错。 推荐用 any 的地方优先用 unknown,因为 unknown 至少类型安全。
function invokeAnything(callback: unknown) {
// you cannot operate on `unknown` type
// before doing a type check or type assertion
if (typeof callback === 'function') {
callback();
}
}
invokeAnything(1);
undefinde和null的区别
- undefined是一个没有被分配值的变量
- null是一个被人为分配的空值
在namespace里面使用
// 用法1
export enum TaskAttribute {
TaskId = 0,
Progress,
TaskType,
Duration,
Moving = 0x1000,
Start,
End,
UserData = 0x2000,
Cookie,
Session,
}
// 用法二
class EventManage {
constructor(props) {
this.name = props.name
}
}
export namespace DownloadEventManage{
const eventManage = new EventManage();
export function getEventManage() {
return eventManage
}
}