【做中学】typescript实际场景使用

14 阅读1分钟

由实际使用例子展开:

  • 获取对象中属性的值的方法
function getProp(obj, attr) {
    return obj[attr]
}
let obj = { name: "jack", age: 10 }
getProp(obj, 'age')

添加完整类型约束如下:

interface IUser {
    name: string,
    age: number,
}
function getProp<T extends keyof IUser>(obj: IUser, attr: T):IUser[T] {
    return obj[attr]
}
let obj: IUser = { name: "jack", age: 10 }
getProp(obj, "age")

其中使用到了 interface,泛型,extends,keyof 的使用,其中 keyof 作用于 interface 或者 type,对比的 typeof 则是作用于 obj,使用比较如下:

// keyof,对类型进行操作,取类或者interface的键组成联合类型
interface IUser { name:string, age:number }
type IUserType = { name:string, age:number }

type UserKeys = keyof IUser // 类似 type UserKeys = 'name' | 'age'
type UserKeys2 = keyof IUserType
let key1:UserKeys = 'name'
let key2:UserKeys2 = 'name'

// typeof,对对象进行操作,生成类似 IUser 的结构
let obj = { name: "jack", age: 18 }
type IUserType2 = typeof obj // 类似于 type IUserType2 = { name:string, age:number }
let obj2: IUserType2 = { name: "bob", age: 20 }
  • 通用方法,根据第一个参数,决定其他参数
interface IMessageBoxConfig {
    title?: String,
    content: String,
}
interface IUserInfo {
    /**用户名称 */
    name: String,
}
type ModuleFuncsMap = {
    loading: (visible: Boolean, timeout?: Number) => Array<any>,
    messageBox: (config: IMessageBoxConfig) => Boolean,
    getUserInfo: (id: string) => IUserInfo
}
declare function run<
    K extends keyof ModuleFuncsMap,
    P extends Parameters<ModuleFuncsMap[K]>,
    R extends ReturnType<ModuleFuncsMap[K]>
>(
    moduleName: K,
    ...options: P
): R

let b = run("messageBox", { content: "这是必选的内容" })
let c = run("getUserInfo", "123132")
console.log(c.name, "utils.ts::244行");

但上面的写法,提供了一个入口,实时更改泛型,绕过预期的参数和返回值的限制,如

// 如下,就直接可以更改参数和结果了
run<'messageBox', any, true>('messageBox', { aaa: 100 })

解决方式是,尽量少定义泛型参数

type RunOptions<K extends keyof ModuleFuncsMap> = Parameters<ModuleFuncsMap[K]>;
type RunResults<K extends keyof ModuleFuncsMap> = ReturnType<ModuleFuncsMap[K]>;
declare function run<
    K extends keyof ModuleFuncsMap
>(
    moduleName: K,
    ...options: RunOptions<K>
): RunResults<K>

待续……