ts的type怎么实现二选一 ?

image.png

type modelData = {
  a: Record<string, any>[],
  b: string[],
  c: string[],
}
type userData = {
  d: string[],
}
type OneOf<T, U> = ({ [K in keyof T]?: undefined } & U) | ({ [K in keyof U]?: undefined } & T) extends infer O
  ? { [K in keyof O]: O[K] }
  : never;
// 让modelOrUser符合其中一个类型, 且不能符合另一个类型, 这个oneOf该怎么实现呢
type modelOrUser = OneOf<modelData, userData>
interface tes extends modelOrUser {
  qq: string
}
阅读 9.6k
3 个回答

从 TypeScript 类型定义上来说,如果一个变量 A 或者 B 类型中的一种,会声明为 A | B,但到底是哪一种,只有运行时才能分析出来。运行时一般通过类型断言函数来动态检查类型,并通过断言语法告诉编译器根据返回的 boolean 类型来判断是否可断言为某种特定类型。

示例不用写了,上面链接有,可以抄一个:

function isFish(pet: Fish | Bird): pet is Fish {
  return (pet as Fish).swim !== undefined;
}

和昨天回答你的是一样的解决方案。
https://segmentfault.com/q/10...

type OneOf<T, U> = ({ [K in keyof T]?: undefined } & U) | ({ [K in keyof U]?: undefined } & T) extends infer O
  ? { [K in keyof O]: O[K] }
  : never;
type Without<FirstType, SecondType> = {[KeyType in Exclude<keyof FirstType, keyof SecondType>]?: never};

type MergeExclusive<FirstType, SecondType> =
    (FirstType | SecondType) extends object ?
        (Without<FirstType, SecondType> & SecondType) | (Without<SecondType, FirstType> & FirstType) :
        FirstType | SecondType;

type modelData = {
  a: Record<string, any>[],
  b: string[],
  c: string[],
}
type userData = {
  d: string[],
}
// 让modelOrUser符合其中一个类型, 且不能符合另一个类型, 这个oneOf该怎么实现呢
type modelOrUser = MergeExclusive<modelData, userData>

const a:modelOrUser = {
    a: [],
    b: [],
    c: []
}

const b:modelOrUser = {
    d: [],
}

ts demo

答案来源于 https://github.com/sindresorh... 仓库

在实际场景中可以引入这种 ts 类型库

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题