Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用TypeScript和fp ts进行类型建模,并在使用_Typescript_Functional Programming_Fp Ts - Fatal编程技术网

使用TypeScript和fp ts进行类型建模,并在使用

使用TypeScript和fp ts进行类型建模,并在使用,typescript,functional-programming,fp-ts,Typescript,Functional Programming,Fp Ts,我正在尝试使用TypeScript和fp-ts来让我的脚在建模中湿透 域逻辑和类型,我遇到了这个问题: import { left, right, Either } from "fp-ts/lib/Either"; type MyType = { id: string, isValid: boolean, } type MyValidType = { id: string, isValid: true, } type CreateMyValidType = (t: MyTy

我正在尝试使用TypeScript和
fp-ts
来让我的脚在建模中湿透 域逻辑和类型,我遇到了这个问题:

import { left, right, Either } from "fp-ts/lib/Either";

type MyType = {
  id: string,
  isValid: boolean,
}

type MyValidType = {
  id: string,
  isValid: true,
}

type CreateMyValidType = (t: MyType) => Either<Error, MyValidType>

// Compile error!
const createMyValidType: CreateMyValidType = t => {
  switch (t.isValid) {
    case true:
      return right({
        id: "test",
        isValid: true
      })
    default:
      return left(new Error())
  }
}
当它在
内部时,似乎无法识别正确的类型

我通过指定调用
right
时的类型找到了避免问题的方法,但我不完全理解其含义,因此我不知道这是否是一个坏主意:

return right<Error, MyType2>({
  id: "test",
  isValid: true,
});
返回右键({
id:“测试”,
是的,
});
处理此问题并使其得以编译的正确方法是什么?
谢谢

简短回答

它在TS>=
3.4中正常工作

回答稍微长一点

正如您可能已经注意到的那样,TypeScript通常并不擅长推理。 在代码示例中,您为函数
的返回类型提供了注释,以便TS可以尝试将所有分支统一到预期的返回类型中:如果没有此显式注释,结果会更糟

即使使用手动类型注释,pre-3.4 TS也会“懒惰”,并尝试解析
left
right
函数声明的所有通用类型参数(两者都有
L
R
作为类型参数),而无需在做出选择之前“等待”获得更好的知识。 因此,对于
default
案例,它将
Error
推断为
L
,对于
true
案例,它将
{id:string,isValid:boolean}
推断为
R
。问题是
MyValidType
要求
isValid
为文本
true
(比
boolean
更具体),因此它最终以失败告终

Type '{ id: string; isValid: boolean; }' is not assignable to type 'MyValidType'.
  Types of property 'isValid' are incompatible.
    Type 'boolean' is not assignable to type 'true'.
使用TS>=
3.4
时,
R
将一直处于“未决定”状态,直到过程的后期,当TS实际知道
createMyValidType
的预期(注释)返回类型,并正确地将文本对象视为可分配给声明的返回类型

您可以在官方的变更日志中阅读更多关于此改进的内容,网址为

附注1

该问题实际上与
fp ts
无关,因为在3.4之前,任何通用函数都会出现类似问题:

declare function identity<T>(t: T): T;

function f(): { foo: 'foo' } {
  return identity({ foo: 'foo' });
}
// Type '{ foo: string; }' is not assignable to type '{ foo: "foo"; }'.
//   Types of property 'foo' are incompatible.
//     Type 'string' is not assignable to type '"foo"'.
考虑到JS的易变性,这是一个“安全”默认值。可以使用“
const
断言”更改此行为:

这是
3.4
(请参阅)中的另一个添加项,在您的示例中,由于在
createMyValidType
中有返回类型注释,因此不严格需要它

declare function identity<T>(t: T): T;

function f(): { foo: 'foo' } {
  return identity({ foo: 'foo' });
}
// Type '{ foo: string; }' is not assignable to type '{ foo: "foo"; }'.
//   Types of property 'foo' are incompatible.
//     Type 'string' is not assignable to type '"foo"'.
const foo = 'foo' // Type: "foo"

const fooObj = { foo: 'foo' } // Type: { foo: string }
const fooObj = { foo: 'foo' } as const // Type: { readonly foo: "foo" }