如何将R.pick与TypeScript一起使用
我在尝试类似的东西如何将R.pick与TypeScript一起使用,typescript,ramda.js,Typescript,Ramda.js,我在尝试类似的东西 从“ramda”导入R 从“fs”导入fs 从“路径”导入路径 从“util”导入{promisify} const readFile=promisify(fs.readFile) 导出异步函数discoverPackageInfo():Promise{ 返回readFile(path.join(uuu dirname,“…”,“package.json')) .然后(b=>b.toString()) .then(JSON.parse) .然后(右)选择([ “姓名”, “说
从“ramda”导入R
从“fs”导入fs
从“路径”导入路径
从“util”导入{promisify}
const readFile=promisify(fs.readFile)
导出异步函数discoverPackageInfo():Promise{
返回readFile(path.join(uuu dirname,“…”,“package.json'))
.然后(b=>b.toString())
.then(JSON.parse)
.然后(右)选择([
“姓名”,
“说明”,
“版本”,
]))
}
但是我有
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 ]))
~~~~~~~
src/file.ts:13:3-错误TS2322:类型“{name:string;version:string;description:string;}| Pick”不能分配给类型“{name:string;version:string;description:string;}”。
类型“Pick”缺少类型“{name:string;version:string;description:string;}”中的以下属性:名称、版本、说明
13返回readFile(path.join(uuu dirname,“…”,“package.json'))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14.然后(b=>b.toString())
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
19“版本”,
~~~~~~~~~~~~~~~~
20 ]))
~~~~~~~
我做错了什么?JSON.parse
。解析后的返回类型如下:
.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
,例如,通过使用/类型防护装置:
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();
}
导出异步函数discoverPackageInfo():Promise{
返回readFile(…)。然后(…)
.then(safeParse(assertMyThing))//断言o是T=>(s:string)=>{
const parsed=JSON.parse;
资产fn(已解析);
返回解析;
}
函数断言虚构(o:any):断言o是虚构的{
if(!(“o中的名称”)o!(“o中的版本”)o!(“o中的说明”)
抛出错误();
}
(操场中的外部类型导入可能需要一些时间才能加载,否则将粘贴到您自己的环境中)是的,我知道使用
async
和。那么就不太合适了。async
在这里实际上是不必要的。没有正确的代码就可以工作。但是,我正在构建我的代码,使其在非CPU的任何东西上都具有async,只是为了迫使人们正确思考问题。最终成为一个结构和注释方面的练习n、 我发现它对我很有帮助。非常有帮助,谢谢!有没有更标准/打包的方法来实现这一点?比如,从类型定义生成断言函数?我还没有看过手册(我只是通过练习学习)我很感谢任何指点!我不确定断言函数的生成器。但是有很多自动生成类型的guard库,我个人觉得很吸引人!而且似乎得到了积极的维护和支持。你也可以看看起点。顺便说一句:如果你想使用断言函数,那么基于生成的类型保护,转换应该没有问题,例如。作为参考,我最终得出以下结论:
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();
}