F# 如何使用现有记录类型创建新的记录类型?

F# 如何使用现有记录类型创建新的记录类型?,f#,suave,F#,Suave,我正在尝试使用Suave创建一个简单的Todorestapi。Todo类型定义为: 键入待办事项= {id:Guid 标题:字符串 完成:bool 截止日期:日期时间选项} 当使用Get-By-IdGet/todos/{guid}和Get-ListGet/todos/API时,此类型可以完美工作。但是在创建新的Todo项时,有效负载不包含id属性,因为它将作为DB操作的一部分自动生成。因此,进行了以下REST API调用: POST /todos/ { "title": "Hello

我正在尝试使用Suave创建一个简单的
Todo
restapi。
Todo
类型定义为:

键入待办事项=
{id:Guid
标题:字符串
完成:bool
截止日期:日期时间选项}
当使用Get-By-Id
Get/todos/{guid}
Get-List
Get/todos/
API时,此类型可以完美工作。但是在创建新的
Todo
项时,有效负载不包含
id
属性,因为它将作为DB操作的一部分自动生成。因此,进行了以下REST API调用:

POST /todos/

{
    "title": "Hello world",
    "isComplete": false,
    "deadline": null
}
但是,问题是JSON反序列化中断,因为
id
字段不可用。如何处理这种情况?将
id
声明为
option
感觉不正确,因为这不是正确的抽象。在TypeScript中,我可以使用诸如
省略
拾取
等实用程序类型来创建新类型,如:

export interface Todo {
    id: string;
    title: string;
    isComplete: boolean;
    deadline?: string
}

// Create new Type from existing type!
export type TodoInput = Omit<Todo, 'id'>;

let payload: TodoInput = {
    isComplete: false,
    title: "Hello"
}

导出接口Todo{
id:字符串;
标题:字符串;
isComplete:布尔值;
截止日期?:字符串
}
//从现有类型创建新类型!
导出类型TodoInput=忽略;
let有效负载:TodoInput={
isComplete:错误,
标题:“你好”
}

如何在F#中获得类似的结果?

即使您没有id,您也应该能够反序列化。下面的内容对我很有用。id将为Guid.empty

open Newtonsoft.Json

type Todo =
    { id: Guid
      title: string
    }

let data = JsonConvert.DeserializeObject<Todo>("{\"title\":\"test\"}")
打开Newtonsoft.Json
键入待办事项=
{id:Guid
标题:字符串
}
让data=JsonConvert.DeserializeObject(“{\”title\“:\”test\“}”)

我怀疑F#有这样的操作。您可以使用组合,例如,
Todo
是由
TodoInput
id
组成的组合。在组合中,我将
TodoInput
重命名为
TodoData
。这看起来像是一个域设计问题。简单的方法是有两种类型,一种没有id,另一种有id——这将简化处理记录的代码设计。在将输入发送到数据库之前,创建一个记录NewTodo来捕获输入,并创建一个单独的Todo来处理持久化记录。我不熟悉这种情况,但在类似情况下,我倾向于使用匿名记录进行(反)序列化。