TS类型标注

// 这段代码看看怎么标注
declare function watch(obj: Object): Watcher;

// 函数watch,传入一个对象,得到新对象
const personWatcher = watch({
  firstName: 'John',
  lastName: 'Doe',
  age: 25,
});

// 新对象的on方法可以监听属性的变化
// 这里 on 的泛型参数类型需要和监听的属性的类型一致
personWatcher.on('ageChanged', (oldValue, newValue) => {
  // 相关逻辑
});

第一种方式
约束力小,比如说:监听的字段可以写任何值,也没有提示

//首先
type Watcher = {
  on(
  eventName: string, 
  callback: (oldValue: any, newValue: any) => void): void;
};

第二种方式
TS中可以使用模板字符串,TS的模板字符串是在编译时来确定类型的

type Watcher<T> = {
  on(
    // 这样写过后,有了TS类型提示,但是将类型写死了,改进一下
    // eventName: `${'firstName' | 'lastName' | 'age'}Changed`,

    // keyof 可以动态取出某一个类型中的所有字段名,形成联合类型
    // 对象的字段名类型包括:string 和 symbol,而symbol无法完成这种拼接
    // 需要使用 string & 约束一下
    eventName: `${string & keyof T}Changed`,
    callback: (oldValue: any, newValue: any) => void
  ): void;
};

declare function watch<T>(obj: T): Watcher<T>;

第三种方式

type Watcher<T> = {
  on<K extends string & keyof T>(
    // eventName: `${string & keyof T}Changed`,
    // 为了保证 on 的泛型参数的类型和监听的字段类型一致,直接改为 K
    eventName: `${K}Changed`,
    // 这里参数是 any 类型肯定不可以,也需要动态知道你读取的是哪个字段
    // callback: (oldValue: any, newValue: any) => void
    // K 从哪里来呢,可以从 on 方法的泛型上获取到
    callback: (oldValue: T[K], newValue: T[K]) => void
  ): void;
};

declare function watch<T>(obj: T): Watcher<T>;

const personWatcher = watch({
  firstName: 'John',
  lastName: 'Doe',
  age: 25,
});

// 这里 on 的泛型参数类型需要和监听的属性的类型一致
personWatcher.on<'age'>('ageChanged', (oldValue, newValue) => {
  // 相关逻辑
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值