仅接受返回相同类型的函数的打字稿函数
Typescript function that accepts only functions returning the same type
我想创建一个函数check(f)
,其参数f
必须是returns与其参数类型相同的函数,类型将被推断。例如:
check((v: number) => v + 1); // OK
check((s: string) => s.toLowerCase()); // OK
check((v: number) => v.toString()); // Not OK
我尝试了以下方法:
function check<T>(f: (v: T) => T) { }
check((v: number) => v > 10 ? v : ""); // Shouldn't be OK
奇怪的是,此代码确实在 TypeScript playground(运行s TypeScript 3.5.1)中报告了错误,但在我的 VS Code([=45] =]s TypeScript 3.6.2),它将通用参数 T
推断为 <number | "">
。发生这种情况是因为一些最新的变化吗?如果是这样,我怎样才能仍然编写所需的 check
函数?
更新
以下是重现问题的步骤:
- 创建一个空文件夹。
- 在文件夹内创建文件test.ts,内容为上述示例代码。文件夹中没有其他文件,因此没有 tsconfig.json,因此所有设置都是默认设置。
- 用 VS Code 打开文件夹,然后打开 test.ts。编辑器显示代码没有错误。将光标悬停在
check
函数上方显示它被推断为 check<number | "">
.
- 打开控制台并运行
tsc test.ts
。构建成功,没有错误。
你的问题是你没有使用 --strict
编译器选项;具体来说,您需要启用 the --strictFunctionTypes
option 才能开始收到您期望的错误。它与 TypeScript 的 3.5 版和 3.6 版无关。您(可能无意中)要求参数双方差,这就是您得到的。
关闭 --strictFunctionTypes
后,函数将不安全地成为 bivariant in their parameter types,这意味着您可以 缩小 它们接受的类型。 扩大它们接受的类型是安全的(因为每个接受 number | ""
的函数也是一个接受 number
的函数,如果我期待后者)但是 narrow 它是不安全的(因为不是每个接受 number
的函数也是接受 number | ""
的函数,你如果我期望后者,真的不应该给我前者)。尽管如此,双变性在某些情况下 很有用 不安全,因此它的某种形式可能会在 TypeScript 中存在,至少会持续一段时间,并且可能永远存在以实现向后兼容性。
除非您想要参数双方差,否则您应该打开--strictFunctionTypes
,并且可能只是--strict
。希望这能满足您的需求。好的;希望有所帮助。祝你好运!
我想创建一个函数check(f)
,其参数f
必须是returns与其参数类型相同的函数,类型将被推断。例如:
check((v: number) => v + 1); // OK
check((s: string) => s.toLowerCase()); // OK
check((v: number) => v.toString()); // Not OK
我尝试了以下方法:
function check<T>(f: (v: T) => T) { }
check((v: number) => v > 10 ? v : ""); // Shouldn't be OK
奇怪的是,此代码确实在 TypeScript playground(运行s TypeScript 3.5.1)中报告了错误,但在我的 VS Code([=45] =]s TypeScript 3.6.2),它将通用参数 T
推断为 <number | "">
。发生这种情况是因为一些最新的变化吗?如果是这样,我怎样才能仍然编写所需的 check
函数?
更新
以下是重现问题的步骤:
- 创建一个空文件夹。
- 在文件夹内创建文件test.ts,内容为上述示例代码。文件夹中没有其他文件,因此没有 tsconfig.json,因此所有设置都是默认设置。
- 用 VS Code 打开文件夹,然后打开 test.ts。编辑器显示代码没有错误。将光标悬停在
check
函数上方显示它被推断为check<number | "">
. - 打开控制台并运行
tsc test.ts
。构建成功,没有错误。
你的问题是你没有使用 --strict
编译器选项;具体来说,您需要启用 the --strictFunctionTypes
option 才能开始收到您期望的错误。它与 TypeScript 的 3.5 版和 3.6 版无关。您(可能无意中)要求参数双方差,这就是您得到的。
关闭 --strictFunctionTypes
后,函数将不安全地成为 bivariant in their parameter types,这意味着您可以 缩小 它们接受的类型。 扩大它们接受的类型是安全的(因为每个接受 number | ""
的函数也是一个接受 number
的函数,如果我期待后者)但是 narrow 它是不安全的(因为不是每个接受 number
的函数也是接受 number | ""
的函数,你如果我期望后者,真的不应该给我前者)。尽管如此,双变性在某些情况下 很有用 不安全,因此它的某种形式可能会在 TypeScript 中存在,至少会持续一段时间,并且可能永远存在以实现向后兼容性。
除非您想要参数双方差,否则您应该打开--strictFunctionTypes
,并且可能只是--strict
。希望这能满足您的需求。好的;希望有所帮助。祝你好运!