我希望能够创建一个新的类型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类型。
1条答案
按热度按时间cetgtptt1#
为了提供一个尽可能接近我的用例的答案,我现在要做的是:
它确实允许您在创建表示模型的类型时忘记包含id属性,但是函数定义会导致typescript给予关于这一点的警告,这正是我想要的。
范例