typescript使用笔记二

// TS 开发准则: 只要是变量、或者对象属性,都应该有一个明确的类型
// 类型注解: 人工的告诉 TS,变量或者对象的明确属性类型
const userName: string = '123'
// 类型推断
const userAge = 18;
// 如果类型推断能够自动推断出来类型,就没必要去手写类型注解
let userNick = 'dell';
userNick.toLocaleUpperCase();
// 这种返回值就不用给,能够自动推断出两个number类型相加,返回的一定是number
function getTotal(paramOne: number, paramTwo: number) {
	return paramOne + paramTwo;
}
getTotal(1,2);

// 如果类型推断推断不出来,或者推断的不准确,再去手写类型注解
const userInfo = {
	name: ' dell'
	age: 18
}

// typeof 类型收窄
function uppercase(content: string | number) {
	if(typeof content === 'string'){
		return content.toUpperCase();
	}
	return content;
}
// 真值收窄
function getString(content?: string) {
	if(content) {
		return content.toUpperCase();
	}
}
// 相等收窄
function example(x: string | number, y: string | boolean) {
	if(x === y) {
		return x.toUpperCase();
	}
}

// 对象类型解构的代码怎么写
function getOjbectValue({a, b}: {a: string, b: string}){
	return a + b;
}
getOjbectValue({a:'1',b: '2'});

// 变量类型以定义变量时的类型为准
let userName = '123';  // 这里就会自动判断类型为string,后面使用这个变量必须传string类型,否则会报错
userName = '123';

type Fish = { swim: () => {} }
type Bird = { fly: () => {} }
// In 语法下的类型收窄
function test(animal: Fish | Bird) {
	if('swim' in animal) {
		return animal.swim();
	}
	return animal.fly();
}
// Instanceof 语法下的类型收窄
function test1(param: Date | string) {
	if(param instanceof Date) {
		return param.getTime();
	}
	return param.toUpperCase();
}
// animal is Fish 叫做类型陈述语法 
function isFish(animal: Fish | Bird): animal is Fish {
	if((animal as Fish).swim !== undefined) {
		return true
	}
	return false;
}
function test2(animal: Fish | Bird) {
	if(isFish(animal)) {
		return animal.swim();
	}
	return animal.fly();
}
// 有属性的函数类型定义方法
interface FunctionWithAttributes {
	attr: string;
	(str: string): void;
}
const test: FunctionwithAttributes = (str: string) => {
	console.log(str);
}
test.attr = 'attributes';

// 构造函数的类型如何定义
interface ClasswithConstructor {
	new (str: string): void;
}
function testOne(outerClass: ClassWithConstructor) {
	const instance = new outerClass( 'new' )
}
class TestOne {
	name: string;
	constructor(str: string) {
		this.name = str;
	}
}
testOne(TestOne);

// 如何写 Date 的类型
interface DateTpye {
	new (): Date; // 如果是一个Date类型
	(dateString: string): string; // 如果是一个函数,就返回一个string类型
}

// 函数和泛型
function getArrayFirstItem<Type>(arr: Type[]): Type{ // type泛型,根据数组里面的内容会自行判断是什么类型
	return arr[0];
}
const numberArr = [1,2,3];
const result = getArrayFirstItem(numberArr);
const stringArr = ['1', '2','3'];
const resultOne = getArrayFirstItem(stringArr);

// 函数重载
function getString(str: string): string; // 重载函数的定义
function getString(str: string, str1: string): number; // 重载函数的定义
function getString(str: string,str1?: string) { // 重载函数的实现
	if(typeof str1 === 'string') {
		return (str + str1).length;
	}
	return str;
}

function showPerson({name: nick = 'dell', age: old = 30}) { // 将name和age解构通过nick和old打印出来
	console.Log(nick);
	console.log(old);
}

// 对象类型和对象解构语法要分清
function showPerson({name = 'dell', age = 30}: {name: string, age: number}) {
	console.log(name);
	console.Log(age);
}
// interface 中的 readonly 只读属性
interface Person {
	readonly name: string;
	age: number;
}
const dell: Person = {name: 'dell', age: 30};
dell.name = 'wayne'; // 会报错,因为name只允许读,不允许修改
dell.age = 30;

//如何给对象扩展属性
interface ArrayObject {
	[key: string]: string | number | boolean;  // 表示可以往里面添加内容,但是键必须是字符串类型
	length: number;
}
const obj: ArrayObject = {
	ad: '123',
	test: true,
	length: 0
}

// 对象类型的继承
interface Animal {
	name: string;
	age: number;
	breath: () => void;
}
interface Dog extends Animal { 
	bark: () => void;
}
const animal: Animal = {
	name: ' panda'
	age: 1,
	breath: () => {}
}
const dog: Dog = {
	name: 'panda'
	age: 1,
	breath:() =>{},
	bark: () =>{}
}

// 多个对象类型同时进行集成
interface Circle {
	radius: number;
}
interface Colorful {
	color: string;
}
interface ColorfulCircle extends Circle, Colorful {}
const colorfulCircle: ColorfulCircle = {
	radius: 1,
	color: 'red'
}

// 交叉类型
type ColorfulCircleOne = Circle & Colorful;
const colorfulCircleOne: ColorfulCircleOne = {
	radius: 1,
	color: 'red'
}

// 泛型  type就是泛型,可以理解为泛型就是一个你所要使用时传的一个值,例如string、number、boolean等等
interface Box<Type> {
	content: Type
}
const box: Box<string> = {
	content: 'box'
}
const box1: Box<number> = {
	content: 123
}
const box2: Box<boolean> = {
	content: true
}

// 使用泛型来扩展生成新的类型
type TypeOrNull<Type> = Type  null;
type OneOrMany<Type> = Type Type[];
// type OneOrManyrNull<Type> = OneOrMany<Type> null;
type One0rMany0rNull<Type> = TypeOrNull<One0rMany<Type>>;

// 数组和泛型
interface SelfArray<Type> {
	[key: number]: Type;
	length: number;
	pop(): Type | undefined;
	push(...items: Type[]): number;
}
const numberArr: SelfArray<string> = ['1','2','3'];

// 数组的 Readonly 修饰符
function doStuff(arr: readonly string[]){
	arr.push('123'); // 会报错,因为只读,push是会修改数组,所以会报错
}

// 元组
type Point = [number, number];
function getPoint([x,y]: Point) {
	return x + y;
}
const point: Point = [1, 2];
getPoint(point);

// 元组 Readonly 
type Point = readonly [number, number,string];
function getPoint([x,y,z]: Point) {
	return x + y + z;
}
const point: Point = [1, 2'string'];
point[0] = 3;  // 会报错,只允许读,不允许修改
getPoint(point);

// extends 和泛型的结合,解决固定参数传递需求
interface Person {
	name: string;
}
function getName<Type extends Person>(person: Type) {
	return person.name;
}
getName({name: 'dell', age: 30, gender: '123123'}); // 配合泛型使用,传入person里面没有的属性也不会报错,但是name就是必填项

// keyof  指的是对象类型中的某一项
interface Teacher {
	name: string;
	age: number;
	sex: 'male'| 'female';
}
const teacher:Teacher = {
	name: 'Dell'
	age: 30sex: 'male'
}
function getTeacherInfo<T extends keyof Teacher>(teacher: Teacher, key: T){
	return teacher[key];
}
getTeacherInfo(teacher, 'name');

// 条件类型: 是根据条件,生成一个新的类型
interface Animal {
	breath: () => {}
}
interface Dog extends Animal {
	bark: () => {}
}
interface Tank {
	pH: number
}
type Example = Tank extends Animal ? string : number; // tank是否继承了animal,如果继承了则给example负值string

// 使用条件类型的例子,可以让我们的函数重载的语法更简练
Iinterface IdLabel {
	id: number;
}
interface NameLabel {
	name: string;
}
type IdOrNameLabel<T> = T extends number ? IdLabel : NameLabel;
function createlabel<T extends string | number>(key: T): IdOrNameLabel<T>;
function createLabel(key: string number): IdLabel | NameLabel {
	if(typeof key === 'string') {
		return { name: key }
	}
	return { id: key }
}
const label = createLabel('dell');
const label1 = createLabel(123);

// 条件类型其他的应用场景
type Type0fMessages<T> = T extends { message unknown} ? T['message']: never;
interface Email {
	from: string,
	to: string;
	message: string;
}
const emailObject: Email = [
	from: 'dell@qq.com',
	to: 'leeagg.com'
	message: 'hello lee'
}
const email: Type0fMessage<Email> = 'hello lee';

// 条件类型其他使用场景
type GetRetureType<T> = T extends (...args: never[]) => infer RetureType ? RetureType : never;
type example = GetRetureType<() => string>;
type example1 = GetRetureType<string>;

// 条件类型其他使用场景
type ToArray<T> = [T] extends [any] ? T[]: never; // 这样就可以让数组里面既可以是string类型也可以是number类型
type StringOrNumberArray = ToArray<string | number>;
type NeverType = ToArray<never>;

// 基础映射类型
// 将只读属性readonly关键字删掉,使用-readonly
interface User {
	readonly name: string;
	readonly age: number;
	male?: boolean;
}
type FilterReadOnly<Type> = {  // -readonly将只读关键字删掉,-?,将非必填改成必填
	- readonly [Property in keyof Type] - ? : Type[Property];
}
type PublicUser = FilterReadOnly<User>;
const publicUser: PublicUser = {
	name: ' dell',
	age: 30,
	male: true,
}
publicUser.age = 31;

// 映射类型高级语法
// 1. exclude  将某个字段从中删除
interface User {
	name: string;
	age: number;
	male: boolean;
}
type DeleteMaleProperty<Type> = {
	[Property in keyof Type as Exclude<Property, 'male'>]: Type[Property];
}
type UserWithoutGender = DeleteMaleProperty<User>;
const user: UserwithoutGender = {
	fname: ' dell'
	age: 30,
}

// 2。字面量语法例子
interface User {  // 转化前的
	name: string;
	age: number;
	male: boolean;
}
interface UserFunctions {   // 想转化成的
	getName: ()=> string;
	getAge: ()=>number;
	getMale: ()=> boolean;
}
type GetPropertyFunctions<Type> = {
	[Property in keyof Type as 'get$(Capitalize<string & Property>)']: () => Type[Property];
}
type UserFunctionsType = GetPropertyFunctions<User>;

// 3.union 类型使用
type SquareEvent = {
	kind: 'square';
	x: number;
	y: number;
}
type CircleEvent = {
	kind:'circle';
	radius: number;
}
type GenerateEventsFunctions<Events extends { kind: string }> = {
	[Event in Events as Event[' kind']]: (event: Event) => number;
}
type NewType = GenerateEventsFunctions<SquareEvent | CircleEvent>

// 类
class Person {
	name = ' dell';
	getName() {
		return this.name;
	}
}
class Teacher extends Person { // 类的继承
	fgetTeacherName() {
		return 'Teacher';
	}
	getName(){
		return super.getName() + 'lee';  // 通过super调用父类的方法
	}
}
const teacher = new Teacher();


// private,protected,public 访问类型
// public 允许我在类的内外被调用
// tprivate 允许在类内被使用
// protected 允许在类内及继承的子类中使用
class Person {
	protected name: string;
	public sayHi(){
		this.name;
		console.log('hi');
	}
}
class Teacher extends Person {
	public sayBye() {
		this.name;
	}
}

// constructor   构造器
class Person {
	// 传统写法
	// public name: string;
	// constructor(name: string) {
	// this.name = name!
	// }
	// 简化写法
	constructor(public name: string) {}
}
const person = new Person('dell') // 会将这个dell直接赋值给 constructor

// 子类也有构造器 子类如果使用构造器,一定得用super调用父类的构造器
class Person {
	constructor(public name: string) {}
}
class Teacher extends Person {
	constructor(public age: number) {
		super('dell');  // 这个super是指必须给父类的构造器传参,否则会报错
	}
}
const teacher = new Teacher(28)

class Person {
	constructor(private _name: string) {}
	get name() {
		return this._name + ' lee';
	}
	set name(name: string) {
		const realName = name.split(  ')[0]
		this._name = realName
	}
}
const person = new Person('dell')

class Demo {
	private static instance: Demo;
	private constructor(public name: string) {}
	static getInstance() {
	if (!this.instance) {
		this.instance = new Demo('dell lee');
		return this.instance;
	}
}
const demo1 = Demo.getInstance();
const demo2 = Demo.getInstance();

// 抽象类   使用abstract关键字,抽象类只能被继承,不能实例化
abstract class Geom {
	width: number;
	getType() {
		return 'Gemo';
	}
	abstract getArea(): number;
}
class Circle extends Geom {
	getArea() {  // 抽象方法也得自己在子类实现,否则会报错
		return 123;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值