类型断言

作用 : 手动指定值的具体类型 ( 缩写值的范围 )

应用场景 1

获取 DOM 元素的时候指定具体元素

示例 :

const box = document.getElementById('img')
console.log(box.src) // ts报错

错误内容 :
【进阶】TS 中的 类型断言 和 泛型

解析 :
上述语法在 js 中可以直接使用, 但是 TS 中就不行啦, 由于类型不明确会报错

解决方法 : 使用类型断言明确具体类型

语法 : let 变量 = 值 as 类型

实例 :

技巧: 获取 DOM 元素类型的方法

【进阶】TS 中的 类型断言 和 泛型

应用场景 2

知道获取数据的类型, 但是不知道具体的数据时 , 使用类型断言后就会有提示

type User = {
  name: string,
  age: number
}
const u1 = {} as User
console.log(u1.name) // 这里就会有提示

非空断言

作用 :
明确地知道对象的属性一定不会为空,可以使用非空断言 !

应用场景 : TS 中 使用 useRef()

【进阶】TS 中的 类型断言 和 泛型

JS 中的语法直接使用会报错

错误解析 :

解决方法 :

function App() {
  const inputRef = useRef<HTMLInputElement>(null)
  return (
    <div className="App">
      <input type="text" ref={inputRef} />
      <button onClick={() => {
        console.log(inputRef.current!.value)
      }}>点击</button>
    </div>)
}

typeof

TS 中的 typeof 操作符 和 js 中的一样都是用来获取变量或属性类型

使用方法 :

获取类型 : type 变量 = typeof 常量

使用 : function(参数:变量){参数.常量的方法}

应用场景

获取到一个复杂的对象,我们把它当做实参传给一个函数fn,但是没有办法在使用形参时获取提示信息

typeof 解决

const res = { name: '小花', city: '武汉',  skills: ['js', 'css'] }
type Stu = typeof res
function fn(obj:Stu) {
    // 这里写 obj. 就会有提示
    obj.skills
}
fn(res)

【进阶】TS 中的 类型断言 和 泛型

注意 : typeof 只能用来查询变量或属性的类型,无法查询其他形式的类型(比如,函数调用的类型)

keyof

获取对象类型的属性名 , 得到新的类型

使用方法

获取类型的属性名 :

使用 : let 变量:T = 'a'

泛型

什么是泛型

顾名思义就是多个类型 , TS 中指使用变量保存要使用的类型

泛型本质

泛型本质是参数化类型 , 就是所操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和函数的创建中,分别成为泛型类泛型接口泛型函数

泛型函数

什么是泛型函数 :

这个函数的参数类型或者返回值的类型是可变的

定义泛型函数 :

function 函数名<类型参数> (形参:类型参数):类型参数{}

使用泛型函数

示例

 // 泛型函数
    function useState<T>(val: T | (() => T)): [T | (() => T), (newvalue: T) => void]{
       return [val,(newvalue)=>{val=newvalue}]
    } 
    const [str,setStr] = useState('1')
    const [num,setNum] = useState<number>(1)
    const [fn, setFn] = useState<number>(() => 1)

泛型推论

泛型推论就是, 利用类型推论简化函数调用

泛型对象

应用场景 :

函数中传入对象和该对象的属性,要求得到给对象的值

  // 泛型对象
    function getProp<T, K extends keyof T>(arr: T, key: K) {
        return arr[key]
    }
    let obj ={name:'ikun',age:18,hobby:'学习'}
    getProp(obj,'hobby')

解析 :

上述约定后, 后续调用时会有提示
【进阶】TS 中的 类型断言 和 泛型

泛型的问题

太灵活了

function fn<T>(value: T): T {
  // 这里value. 不会有提示
  console.log(value.length)// 这里会报错
  return value
}
fn('a')

【进阶】TS 中的 类型断言 和 泛型

解决泛型太灵活的方法

为泛型添加约束来收缩类型(缩窄类型取值范围)

泛型约束

泛型约束主要有以下两种方式:

指定更加具体的类型

指定更具体的类型缩小范围

function fn<T>(value: T[]): T[] {
  console.log(value.length) // 这里就可以获得提示
  return value
}

T[] 数组一定会有length属性

添加约束(推荐使用)

对已有类型做继承,已有类型中指定了 length属性

 interface ILength { length: number }
    function fn1<T extends ILength>(value: T): T {
        // 这里value. 不会有提示
        console.log(value.length)
        return value
    }

泛型接口

在接口中使用泛型来使用,以增加其灵活性,增强其复用性

语法 :

interface 接口名<类型变量1,类型变量2...> {
  属性名1:类型1,
  属性名2:类型2,
  属性名3:类型3
}

注意 :

实例:

interface MyArray {
  length: number,
  push(n: number):void,
  pop():number,
  reverse():number[]
}
let obj: MyArray = {
  id(value) { return value },
  ids() { return [1, 3, 5] }
}

数组在ts中就是一个泛型接口
【进阶】TS 中的 类型断言 和 泛型

泛型工具类型

Partial

把已有的类型属性,变成一个新类型的可选属性

语法 : type 新类型 = partial<老类型>

Readonly

把已有类型全部转换为只读类型

语法和上述一直

定义对象使其内在属性不能修改

Pick

从已有类型中选一些属性来构造新的类型

语法 : type 新类型 = partial<老类型,属性|属性2>

详见代码

代码地址: github.com/jiang-zi/TS…

发表回复