当前位置: 首页 > 知识库问答 >
问题:

如何使用r.pick与TypeScript

郦翰学
2023-03-14
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<{
  name: string,
  version: string
  description: string
}> {
  return readFile(path.join(__dirname, '..', 'package.json'))
    .then(b => b.toString())
    .then(JSON.parse)
    .then(R.pick([
      'name',
      'description',
      'version',
    ]))
}
src/file.ts:13:3 - error TS2322: Type '{ name: string; version: string; description: string; } | Pick<any, never>' is not assignable to type '{ name: string; version: string; description: string; }'.
  Type 'Pick<any, never>' is missing the following properties from type '{ name: string; version: string; description: string; }': name, version, description

 13   return readFile(path.join(__dirname, '..', 'package.json'))
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 14     .then(b => b.toString())
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
... 
 19       'version',
    ~~~~~~~~~~~~~~~~
 20     ]))
    ~~~~~~~

我做错了什么?

共有1个答案

邹学民
2023-03-14

json.parse返回任意r.pick之后的返回类型如下所示:

.then(R.pick([ 'name', 'description', 'version' ])) 
=>
type Return = Pick<any, Inner> // 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):

readFile(path.join(__dirname, "..", "package.json"))
  .then(b => b.toString())
  .then(s => JSON.parse(s) as MyThing)
  .then(R.pick(["name", "description", "version"]));

可以使解析更加类型安全,例如通过使用断言函数/类型保护:

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) => {
  const parsed = JSON.parse(s);
  assertFn(parsed);
  return parsed;
}

function assertMyThing(o: any): asserts o is MyThing {
  if (!("name" in o) || !("version" in o) || !("description" in o))
    throw Error();
}
 类似资料:
  • Typescript在这行抱怨道: 我得到这个错误: 因为postId被接收为<code>req.params。postId</code>它是string类型,所以我将其转换为mongoose objectId,但仍然有相同的错误: pull() 在猫鼬数组中工作。这行代码是我在javacsript中实现的。我正在将我的项目转换为打字稿。这是用户模型的用户界面和架构。 这里发布架构和界面

  • 我发现了osmbonuspack,但是wiki中的API信息和文档非常少。 http://code.google.com/p/osmbonuspack/ 我认为这个库对升级osmdroid很有意思,但我无法学会使用它。 已经被人利用了?

  • 我试图设置我的vuejs应用程序,但我不知道如何正确配置这个与我的webpack配置html lint。我目前正在尝试htmlhint-loader。我使用以下命令安装了它: 并在我的网页中添加了以下代码。基础配置: 但这不起作用,让我知道,如果还有什么需要使它工作。 当我使用这个正则表达式时: 我发现以下错误: 错误/~/html网页包插件/lib/loader。js/指数html模块分析失败:

  • 我试图使用ESLint linter与Jest测试框架。 Jest测试使用一些全局变量运行,比如,我需要告诉linter关于它的信息;但棘手的是目录结构,Jest将测试与源代码一起嵌入文件夹中,因此目录结构类似于: 通常,我会将所有测试放在一个目录下,我可以在那里添加一个文件来添加全局变量。。。但是我当然不想在每一个目录中添加文件。 目前,我刚刚将测试全局变量添加到了global文件中,但由于这意

  • 问题内容: 我正在尝试使SystemJS与Typescript一起使用,但是它们似乎彼此冲突。 我如何利用System.js的自动加载功能而不会与Typescript上的关键字发生冲突?使用import / require可以使Typescript使用它自己的方式来加载和引用文件,尽管它转换为,但对于 是否有可能完全做到这一点,否则我将不得不等待Typescript支持ES6关键字? 问题答案:

  • 问题内容: 我最近安装了隐私vpn,事实证明启用的openvpn会破坏docker。 当我尝试运行时,出现以下错误 禁用vpn可以解决此问题(但是我宁愿不禁用它)。有什么办法可以使这两者和平共处?我使用debian jessie,并且我的openvpn具有以下版本字符串 很多人通过禁用openvpn来“解决”此问题,因此我专门询问如何使这两个工具同时工作。 如果这有什么不同,我的vpn提供程序是: