TypeScript创建从扩展类型省略类型

3vpjnl9f  于 2022-11-26  发布在  TypeScript
关注(0)|答案(1)|浏览(165)

我希望能够创建一个新的类型DataObject,它只需要省略扩展Model接口的接口的id属性。因此DataObject应该需要T的所有属性,除了id,并禁止任何其他属性。我定义了以下类型/接口:

type DataObject<T extends Model> = Omit<T, "id">

interface Model extends JSONObject {
  id: string
}

interface JSONObject {
  [key: string]: JSONValue
}

type JSONArray = JSONValue[]

type JSONValue = PrimitiveValue | JSONObject | JSONArray

type PrimitiveValue = string | number | boolean

然后我有几个函数接受给定类型的数据对象,并将数据插入数据库,模式与下面类似:

// identifier is the table name, optionally with the id provided "tablename:id"
function insert<T extends Model>(identifier: string, data: DataObject<T>) {
  //...inserts data
}

但是,当我使用这个函数时,它并没有强制执行我希望它执行的类型;如果我试图给它一个数据对象,该对象包含扩展Model的给定接口中未定义的任何属性(除了id),并且如果它缺少任何属性(除了id),我希望它给予一个错误。

interface Person extends Model {
  name: string,
  age: number
}

// this should not be valid
insert<Person>({
  foo: "bar",
  id: "a1b2"
})

// This should not be valid either
const personData: DataObject<Person>{
  name: "John",
  id: "12345"
}

如果DataObject简单地采用任何类型T,它都可以工作,但是我希望它是Model的一个扩展。这可能吗?
更多背景信息:我希望在插入数据时排除id的原因是,数据库负责创建记录id,但在从数据库检索记录时,id属性是存在的,这就是为什么Model总是有它的原因。
我试过定义我自己的Omit类型并使用它。也试过直接在函数定义中定义DataObject类型。

cetgtptt

cetgtptt1#

为了提供一个尽可能接近我的用例的答案,我现在要做的是:

type Person = {
  name: string,
  age: number,
  id: string
}

它确实允许您在创建表示模型的类型时忘记包含id属性,但是函数定义会导致typescript给予关于这一点的警告,这正是我想要的。
范例

相关问题