typescript - 将函数作为参数传递时如何添加类型安全?

标签 typescript typescript-generics

关于泛型,我很好奇如何正确键入函数参数。

看下面的基本示例,我有 2 个函数: - sayHello & runAnyFunction

现在,第一次调用 sayHello 显然是一个错误,传递给该函数的数据没有 name 参数。完美且符合预期。

问题出在下一部分,我们有一个函数 runAnyFunction,它将一个函数作为它的第一个参数,obj 作为它的第二个参数,并简单地运行将 obj 作为参数传递的函数。

下面示例中的以下 2 个函数将毫无问题地通过 typescript 检查,这是我的问题。

runAnyFunction<Person>(sayHello, {
  name: "Bob"
});

runAnyFunction<Monster>(sayHello, {
  size: "HUGE"
});

我知道第二次调用会给我一个 Hello undefined,这是不希望的。理想情况下,我希望此调用无法通过类型检查,因为这是不允许的。

我的想法是这里的罪魁祸首是 fn 函数参数,因为它自己的 obj 参数将被推断为 any,但我'为此编写正确的类型有困难。

我知道在这个演示中,我的 runAnyFunction 是一个实际上只运行任何函数的函数,但是如果有一种首选的方式来键入这种性质的函数,我很想知道。

如何正确输入?


代码示例

// demo.ts

type Fn = (obj) => string;

interface Person {
  name: string;
}

interface Monster {
  size: string;
}

const somePerson: Person = {
  name: "Bob"
};

const someMonster: Monster = {
  size: "HUGE"
};


sayHello(someMonster); // ERROR, 'name' is missing in type. Sure, expected.


// sayHello requires an obj of type Person
export function sayHello(obj: Person): string {
  return `Hello ${obj.name}`;
}

// Simple function that runs any function, passing obj to it
export function runAnyFunction<T>(fn: Fn, obj: T): void {
  const res = fn(obj);
  console.log(res);
}

// Person has name, this works
runAnyFunction<Person>(sayHello, {
  name: "Bob"
});

// I'm passing sayHello, which should require an object with a `name`
// but it does not error
runAnyFunction<Monster>(sayHello, {
  size: "HUGE"
});

最佳答案

您还需要使您的 Fn 类型通用:

type Fn<T> = (obj: T) => string;
export function runAnyFunction<T>(fn: Fn<T>, obj: T): void {
    const res = fn(obj);
    console.log(res);
}

您之前没有收到错误的原因是您的 Fn 类型隐含的第一个参数是 any 类型:

type Fn = (obj) => string; // obj is implicitly of type any

关于typescript - 将函数作为参数传递时如何添加类型安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55203358/

相关文章:

typescript - 是否可以从 TypeScript 的类型推断中排除 "this"?

javascript - 在外部文件的 typescript 中声明 var 获取 ReferenceError : . .. 未定义

typescript - 类型不可分配给类型 2322

typescript - TypeScript 如何推断回调参数类型

typescript - 如何让 typescript 推断通用对象数组中参数的值?

reactjs - 如何使用 typescript 为 HOC 编写通用类型?

javascript - new Date() 从 typescript 类创建错误的日期

Typescript - 获取 typeof 函数参数

html - React - 如何修改 root 中的 html?

TypeScript Generic Factory Function Type,匹配数组元素顺序