typescript笔记

88 阅读4分钟

1.范型:定义函数或类的时候,如果遇到不明确的就可以使用范型

function fn<T>(a: T): T{
    return a
  }
  fn(10)
function fn<T, K>(a: T, b: K): T{
    return a
  }
  fn(10,'aa')
function fn1<T extends inter>(a: T){
    return a.length
  }
  fn1('aaa')
class MyClass<T>{
    name: T
    constructor(name: T){
      this.name = name
    }
  }
  const a  = new MyClass({name: 'aaa'})

2d.ts的作用

在TypeScript中,.d.ts文件是类型声明文件的一种形式,用于描述JavaScript模块的类型信息。这些文件不包含具体的实现代码,而是提供了关于模块、变量、函数、类等在代码中的类型信息,以便在开发过程中进行类型检查、自动补全和文档生成等操作。.d.ts文件通常用于以下几种情况:

  1. 第三方库的类型声明: 当你在TypeScript项目中使用第三方JavaScript库时,你可能需要为这些库编写类型声明文件,以便在TypeScript中获得类型检查和自动补全的好处。如果这些类型声明文件不存在,TypeScript将无法理解库的API并执行类型检查。
  2. 旧版JavaScript模块的类型声明: 如果你要在TypeScript项目中使用旧版的JavaScript模块(使用CommonJS、AMD等模块系统),你可以为这些模块编写类型声明文件,以便在TypeScript中正确地使用它们。
  3. 全局变量和命名空间的类型声明: 有时候,你可能需要在项目中使用一些全局变量或者命名空间。为了让TypeScript知道这些变量的类型,你可以编写相应的类型声明文件。

.d.ts文件通常是以 .d.ts 为后缀名的文本文件,其中包含了对应JavaScript模块、类、函数等的类型描述,例如:

// math.js

/**

  • Adds two numbers.

  • @param {number} a - The first number.

  • @param {number} b - The second number.

  • @returns {number} The sum of a and b.

*/

function add(a, b) {

return a + b;

}

module.exports = { add };

In this example, we've declared a module named 'math' using the declare module syntax. Inside this module declaration, we've exported the add function with its parameter and return types annotated with TypeScript types.

Now, assuming you have a TypeScript file that uses the math module:

// app.ts

import { add } from 'math';

const result = add(5, 3);

console.log(result); // Output: 8

When you use this TypeScript file in your project, TypeScript will recognize the typings from the math.d.ts file, and you'll get proper type checking and autocompletion for the add function.

3.function as types

let unionFunctionType: (a:number,b:number)=>number
    function aa(a:number,b:number){
        return  a+b
    }
    unionFunctionType = aa

4.throw error

function generateError(message:string){
        throw {message}
    }
    generateError('something wrong')

5.回调函数

function addHandler(n1: number,n2: number, cb: (num: number)=>void){
        let result = n1 + n2
        cb(result)
    }
    addHandler(1,2,(result)=>{
        console.log(result)
    })
// 1.keyof、in 与 [] 符号对索引类型的操作

interface Foo{
    a:string;
    b:number;
}
type FooKey = Foo['a']  //string
type FooKey1 = Foo['a'|'b'] //string|number or
type FooKey2 = keyof Foo   // 'a'|'b'
type FooKey3 = Foo[keyof Foo]  //等价于FooKey1

type FooType = 'a' | 'b' | 'c'

/*
    type FooObj = {
        a: any;
        b: any;
        c: any;
    }
*/
type FooObj = {
    [key in FooType]: any
}

//拿partial举例子
interface Person{
    name:string;
    age:number;
    hobby: string;
}
type Person1 = Partial<Person>

type Partail<P> = {
    [T in keyof P]?: P[T]
}

7.get/set

class Person{
    private _name: string;
    constructor(name: string){
        this._name = name;
    }
    get name1(): string{
        return this._name
    }
    set name1(name: string){
        this._name = name
    }
}

const p = new Person('aaa')
console.log(11111,p.name1)
p.name1 = 'aaa1'
console.log(2222,p.name1)

//&

//&
type Admin = {
    privileges: string[],
    name: string
}

type Employee = {
    name:string;
    age: number
}

type A = Employee & Admin
const employee: A = {
    name:'11',
    age:11,
    privileges:['1']
}

//遇到 |,如何判断是哪个

// | 
type unKnown = Employee | Admin
function printInfo(emp:unKnown):void {
    if('privileges' in emp){
        return 
    }
}
//instanceof
class Car{
    go(){
        console.log('go')
    }
}

class Truck{
    aha(){
        console.log('aha')
    }
}

type Vehicle = Car | Truck
function useVehicle(vihicle: Vehicle){
    if(vihicle instanceof Truck){
        vihicle.aha()
    }
}
//type casting
const inputElement = document.getElementById('user-input')! as HTMLInputElement
inputElement.value = 'aaa'
//nullish
const userInput = null
const a = userInput ?? 'Default'

范型相关

//范型在 array or promise
const arr: Array<string> = []
const promise1: Promise<string> = new Promise((resolve,reject)=>{
    setTimeout(() => {
        resolve('a')
    }, 2000);
})
promise1.then(data=>{
    console.log(6666,data)
})

//范型和extends keyof结合
function extractAndConvert<T extends object,K extends keyof T>(obj: T,key: K){
    return obj[key]
}
console.log(8888,extractAndConvert({a:111},'a'))

//
interface CourseGoal{
    title: string,
    des: string
}

function creatCourseGoal(title: string): CourseGoal{
    let goal: Partail<CourseGoal> = {}
    goal.title = title
    return goal as CourseGoal
    
}

装饰器

@Logger1('logging person1')
@Logger2('logging person2')
class ADeractor{
    name='aaa'
    constructor(){
        console.log('in constructor')
    }
}

注意:装饰器只在定义时执行,也可以通过写代码在每次实例化也执行

function Autobind(target: any, methonName: string, descriptor: PropertyDecorator){
    const originalMethod = descriptor.value;
    const adjDecotator:PropertyDecorator = {
        configurable: true,
        enumerable: true,
        get(){
            const boundFn = originalMethod.bind(this)
            return boundFn
        }
    }
    return adjDecotator
}

// autobind
class Priter{
    message = 'this works'
    @Autobind
    showPrinter(){
        console.log(this.message)
    }
}

const p1  = new Priter()
const button = document.getElementById('button')
button?.addEventListener('click', p1.showPrinter)

文章篇

type和inteface的区别

所以说,使用interface定义的类型是可以在之后进行修改的。而使用type定义的类型没有类型合并的特性,定义后就不能够再次修改

infer的使用

infer操作符必须要搭配条件类型(搭配extends关键字)使用,infer是用来用做类型推断并赋值的,后面通常跟一个泛型变量,推断后的返回类型交给后面跟着的泛型变量,用于对其某个方面作出解析。这个操作符通常会在我们书写类型工具的时候起到重要作用。

// 如果成立 infer 能推断出数组中元素的类型并且赋值给 U type Type = T extends Array ? U : T // 判断类型是数组,解析 type Test = Type<string[]> // string // 判断类型不是数组,直接返回 type Test2 = Type // string

内置类型(用于interface定义的)

索引属性

联合类型

全局定义

外部模块定义

juejin.cn/post/698459…你不知道的js/es6/css