Typescript中如何让一个函数参数依赖另一个函数参数?

506 阅读2分钟

image.png当我们使用它的一些更高级的功能时,Typescript会有很大的帮助。在这篇文章中,我们根据一个函数参数的类型来指定另一个参数的类型。

一个场景

比方说,我们有一个对象属性的改变处理程序。在普通的JavaScript中,这个变化处理程序可能看起来像这样。

const user = {
  name: 'Daffodil',
  age: 27,
  admin: false,
};

const changeUser = (key, value) => {
  user[key] = value;
};

够简单了!但如果我们想做一些事情,比如说,我们想把一个对象的属性改变成另一个对象。但是如果我们想在Typescript中做类似的事情呢?

一个天真的方法

让我们采取一种天真的方法。我们可以假设key 将是一个keyof 我们的User 类型,而value 可能是类似User[typeof key] 的东西。

type User = {
  name: string;
  age: number;
  admin: boolean;
};

const user = {
  name: 'Daffodil',
  age: 27,
  admin: false,
};

const changeUser = (key: keyof User, value: User[typeof key]) => {
  user[key] = value;
};

不幸的是,这并不奏效。我们得到一个这样的错误。

image.png

基本上,Typescript编译器并不完全理解如何根据提供的key ,缩小value 的类型。

解决方案:泛型

解决这个问题的方法是泛型!我们可以指定一个泛型,K ,它是一个keyof User 。然后,我们的value 可以是User[K]

下面是这个方法的原理。

type User = {
  name: string;
  age: number;
  admin: boolean;
};

const user = {
  name: 'Daffodil',
  age: 27,
  admin: false,
};

const changeUser = <K extends keyof User>(key: K, value: User[K]) => {
  user[key] = value;
};

很好!我们不再有编译错误,我们的value 参数现在将根据key 参数缩小。为了看到这个动作,让我们看看不同的场景,我们的编译器是否会对我们生气。

image.png

我们看到,当我们为每个键指定正确的类型时,我们的Typescript编译器没有问题,但当为某个键提供错误的类型时,它就会显示错误