有没有更好的方法来构建这个打字稿类型定义?
Is there a better way of structuring this typescript type definition?
我刚开始在我的 Node 项目中使用 TypeScript,我想知道是否有更简洁、更简洁的实现方式:
import { XOR } from "ts-xor";
type _RemoveNull<T> = {
[P in keyof T] : string;
}
type UserIdParam = {
a: string;
}
type BudgetIdParam = UserIdParam & {
b: string | null;
}
type AccountIdParam = _RemoveNull<BudgetIdParam> & {
c: string | null;
}
type TransIdParam = _RemoveNull<AccountIdParam> & {
d: string | null;
}
type IdsParam = XOR<XOR<XOR<UserIdParam, BudgetIdParam>, AccountIdParam>, TransIdParam>;
我想要一个可以接受任何这些示例对象的类型:
const a = {a: "1"};
const b = {a: "1", b: "2"};
const c = {a: "1", b: "2", c: "3"};
const d = {a: "1", b: "2", c: "3", d: "4"};
此外,只有对象的最后一个可用属性可以为null,这就是为什么我必须与之前的类型相交并从联合中删除null。
我尝试对 UserIdParam
、BudgetIdParam
、AccountIdParam
和 TransIdParam
这四种类型进行联合,但在阅读了 等其他问题后,我决定使用异或 (ts-xor) 来完成我需要的。
请告诉我您的想法。谢谢!
--
编辑:正如@Thomas 在评论中提到的,对象属性没有顺序的概念,因此没有“最后”一个。
我能够使用泛型、映射类型和条件类型重新实现它(感谢这个 article 为我指明了正确的方向):
type UserIdKeys = "userId";
type BudgetIdKeys = UserIdKeys | "budgetId" ;
type AccountIdKeys = BudgetIdKeys | "accountId";
type TransactIdKeys = AccountIdKeys | "transactionId";
// added for readability
type AllIdKeys = TransactIdKeys;
type IdParamGroup<T extends AllIdKeys, N extends AllIdKeys> = {
[P in T]: P extends N ? (string | null) : string;
};
这是一个用法示例:
// valid
const trans1: IdParamGroup<TransactIdKeys, "transactionId"> = {
userId: "1",
budgetId: "3",
accountId: "56",
transactionId: null,
}
// invalid
const budget3: IdParamGroup<BudgetIdKeys, "budgetId"> = {
userId: "1",
budgetId: null,
accountId: "23"
}
您可以在这里尝试:TS Playground
我刚开始在我的 Node 项目中使用 TypeScript,我想知道是否有更简洁、更简洁的实现方式:
import { XOR } from "ts-xor";
type _RemoveNull<T> = {
[P in keyof T] : string;
}
type UserIdParam = {
a: string;
}
type BudgetIdParam = UserIdParam & {
b: string | null;
}
type AccountIdParam = _RemoveNull<BudgetIdParam> & {
c: string | null;
}
type TransIdParam = _RemoveNull<AccountIdParam> & {
d: string | null;
}
type IdsParam = XOR<XOR<XOR<UserIdParam, BudgetIdParam>, AccountIdParam>, TransIdParam>;
我想要一个可以接受任何这些示例对象的类型:
const a = {a: "1"};
const b = {a: "1", b: "2"};
const c = {a: "1", b: "2", c: "3"};
const d = {a: "1", b: "2", c: "3", d: "4"};
此外,只有对象的最后一个可用属性可以为null,这就是为什么我必须与之前的类型相交并从联合中删除null。
我尝试对 UserIdParam
、BudgetIdParam
、AccountIdParam
和 TransIdParam
这四种类型进行联合,但在阅读了
请告诉我您的想法。谢谢!
--
编辑:正如@Thomas 在评论中提到的,对象属性没有顺序的概念,因此没有“最后”一个。
我能够使用泛型、映射类型和条件类型重新实现它(感谢这个 article 为我指明了正确的方向):
type UserIdKeys = "userId";
type BudgetIdKeys = UserIdKeys | "budgetId" ;
type AccountIdKeys = BudgetIdKeys | "accountId";
type TransactIdKeys = AccountIdKeys | "transactionId";
// added for readability
type AllIdKeys = TransactIdKeys;
type IdParamGroup<T extends AllIdKeys, N extends AllIdKeys> = {
[P in T]: P extends N ? (string | null) : string;
};
这是一个用法示例:
// valid
const trans1: IdParamGroup<TransactIdKeys, "transactionId"> = {
userId: "1",
budgetId: "3",
accountId: "56",
transactionId: null,
}
// invalid
const budget3: IdParamGroup<BudgetIdKeys, "budgetId"> = {
userId: "1",
budgetId: null,
accountId: "23"
}
您可以在这里尝试:TS Playground