当编写像商店这样的字典的接口时,我想区分数据模型和商店中的项目,即id和模型。我想添加约束,模型本身在其界面中不使用字段id,但我不知道该怎么做。
type Item<T> = T & {id: string}
// T is type of model
// Item<T> is type of objects in the store, use id as primary key
Run Code Online (Sandbox Code Playgroud)
以下函数是简化版,用于在商店中添加新商品
function add<T>(model: Item<T>): T {
const id = uuid();
const result = {...model, id};
store.push(result);
return result;
}
Run Code Online (Sandbox Code Playgroud)
最好在没有属性的T情况下添加一些约束,否则会与 相同,同时in与 中的不一样,这会导致错误。TidTItem<T>idItem<T>T
作为总结,我需要这样的类型
type Item<T extends "The type which allow any type without property id: string"> = T & {id : string}
Run Code Online (Sandbox Code Playgroud)
我尝试过以下方法:
type T0 = Exclude<any, {id: string}>; // any
type T1 = Exclude<{}, {id: string}>; // {}
type SafeModel<T extends Exclude<T, {id: string}>>; //circular constrain
Run Code Online (Sandbox Code Playgroud)
它们都不起作用。
我想要一些类似的东西
type Model // define like this
const v0: Model = {name: 'someName'} // ok
const v2: Model = {value: 123, id: 'someId'} //ok
const v1: Model = {name: 'someName', id: 'someId'} //error
Run Code Online (Sandbox Code Playgroud)
或者绕过循环约束来定义类型的方法,它允许定义
type Model<T> = T extends { id: string } ? never: T;
type Item<T extends Model<T>> = T & { id: string }
Run Code Online (Sandbox Code Playgroud)
Typescript 主要使用结构化类型策略(而不是名义类型)。表达结构应该具有什么而不是不具有什么更容易。
这是完成类似操作的通用类型:
type XorExtend<T extends {
[K in keyof T]: K extends keyof A
? A[K] extends T[K]
? never
: T[K]
: T[K]
}, A extends object,> = T & A
type a = XorExtend<{ id: string }, { a: 1 }> // okay
type b = XorExtend<{ id: string }, { id: 'asdf' }> // not okay!
type c = XorExtend<{ id: string }, { id: 1 }> // okay
Run Code Online (Sandbox Code Playgroud)
游乐场在这里
假设您在某处使用某个函数,您也可以利用以下功能:
declare function xorExtend<O, P extends { [K in keyof P]: K extends keyof O
? O[K] extends P[K]
? never
: P[K]
: P[K]
}>(a: O, b: P): P & O
const test = xorExtend( { id: '' }, { b: '' } ) // ok, test: {id: ''} & {b: ''}
const test2 = xorExtend( { id: '' }, { id: 'whatever' } ) // not okay
const test3 = xorExtend( { id: '' }, { id: 4 } ) // okay
Run Code Online (Sandbox Code Playgroud)
此处链接到游乐场
希望这可以帮助!
这是我在 github 上的要点:
https://gist.github.com/babakness/82eba31701195d9b68d4119a5c59fd35
| 归档时间: |
|
| 查看次数: |
1764 次 |
| 最近记录: |