typescript 我可以用另一个类型扩展一个类型吗?

rfbsl7qr  于 2023-01-14  发布在  TypeScript
关注(0)|答案(1)|浏览(116)

考虑以下类型:

export type Collections = {
  users: User
  business: Business
  permissions: Permissions
  cards: Card
}

// note the Collections[keyof Collections] are just some custom types
// that are objects, but are irrelevant for the question

假设我想创建一个类型来扩展Record<keyof Collections, unknown>中的上述类型
我知道typescript最近引入了statisfies操作符,但这只对const有用,而不扩展类型本身。
我知道我想要的类型的形状,即.

export type SubCollections = {
  cards: [CardLog, CardActions]
  users: [UserLog]
}

这是可行的,但不是很实用,因为当我想使用一个函数时

const subcollection = <K extends keyof Collections, S extends SubCollections[K]>(
  collection: K,
  sub: S
) => // ...

这会抛出一个TypeError:
类型K不能用于索引类型SubCollections
显然我明白为什么会这样,我知道我可以创造一个人工的类型--更窄的类型。

type SharedKey<K extends keyof Collection> = K extends keyof SubCollections
 ? K
 : never

export const subcollection = <
  K extends keyof Collections,
  S extends SharedKey<K>
>(collection: K, subcol: S) => // ...
// ^ this works!

但是,如果我不得不在每个用例中单独缩小论证范围,这仍然会让人觉得相当笨拙。
有没有可能有一种方法可以告诉typescript,这两种类型共享相同的键?

// something akin to (obviously this is invalid syntax)
export type SubCollections extends Record<keyof Collections, unknown[]> = {
  cards: [CardLog, CardActions]
  users: [UserLog]
}
yeotifhr

yeotifhr1#

这可能会有帮助吗?

type Commonkeys<A, B> = keyof A extends infer keyofA ? (keyofA extends keyof B ? keyofA : never) : never;

type AAA = Commonkeys<Collections, SubCollections>;
//  type AAA = "cards" | "users"

const subcollection = <K extends Commonkeys<Collections, SubCollections>, S extends SubCollections[K]>(collection: K, sub: S) => {};

更新感谢vera:

const subcollection = <K extends keyof Collections & keyof SubCollections, S extends SubCollections[K]>(
  collection: K,
  sub: S
) => {};

现在看起来很简单...

相关问题