How to use R.pick with TypeScript
我正在尝试类似
的东西
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import R from ‘ramda’
import fs from ‘fs’ import path from ‘path’ import {promisify} from ‘util’ const readFile = promisify(fs.readFile) export async function discoverPackageInfo(): Promise<{ |
但我得到了
|
1
2 3 4 5 6 7 8 9 10 11 12 |
src/file.ts:13:3 – error TS2322: Type ‘{ name: string; version: string; description: string; } | Pick’ is not assignable to type ‘{ name: string; version: string; description: string; }’.
Type ‘Pick’ is missing the following properties from type ‘{ name: string; version: string; description: string; }’: name, version, description 13 return readFile(path.join(__dirname, ‘..’, ‘package.json’)) |
我做错了什么?
- 是的,我知道使用 async 和 .then 并不太合乎情理。
- async 在这里实际上是不必要的。代码没有它就可以工作
- 正确的。但是,我正在构建我的代码以在非 CPU 的任何内容上进行异步,以便强制正确思考问题。最终成为结构和注释的练习,我发现它对我有很大帮助。
JSON.parse 返回 any。 R.pick 之后的返回类型解析如下:
|
1
2 3 4 5 |
.then(R.pick([ ‘name’, ‘description’, ‘version’ ]))
=> type Return = Pick // resolves to {}; any stems from JSON.parse type Inner = Exclude<keyof any, Exclude<keyof any,”name” |”description” |”version”>> // never |
你想要 { name: string, version: string description: string },但得到 {}。要解决此问题,请为 JSON.parse 显式声明所需的类型(我将其命名为 MyThing):
|
1
2 3 4 |
readFile(path.join(__dirname,”..”,”package.json”))
.then(b => b.toString()) .then(s => JSON.parse(s) as MyThing) .then(R.pick([“name”,”description”,”version”])); |
可以使解析更加类型安全,例如通过使用断言函数/类型保护:
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
export async function discoverPackageInfo(): Promise<MyThing> {
return readFile(…).then(…) .then(safeParse(assertMyThing)) // <– change .then(R.pick(…)); } const safeParse = < T >(assertFn: (o: any) => asserts o is T) => (s: string) => { function assertMyThing(o: any): asserts o is MyThing { |
Playground(playground 中的外部类型导入可能需要一些时间来加载,否则粘贴到您自己的环境中)
- 很大的帮助,谢谢!有没有更标准/打包的方式来做到这一点?比如,从类型定义生成一个断言函数?我没有读过手册(我只是通过练习来学习),我会很感激任何指点!
- 我不确定断言函数的生成器。但是那里有很多自动生成的类型保护库,我个人觉得 io-ts 和 typescript-很吸引人!并且似乎得到了积极的维护和支持。您也可以查看这些帖子作为起点。
- 顺便说一句:如果你想使用基于生成的类型保护的断言函数,转换应该没问题,就像这样。
- 作为参考,我最终得到了这个:gist.github.com/pkoch/9062725ef441d80649f00964f9f424b7
来源:https://www.codenong.com/59482851/
