typescript 用于检查类型是否扩展函数的只读属性的条件泛型

wztqucjr  于 2022-12-19  发布在  TypeScript
关注(0)|答案(1)|浏览(178)

我下面的目标是将p输入为{ size: number | undefined, shape: string },我在创建requiredoptional函数附加到它们的只读required属性的条件时遇到了问题。我尝试了几种不同的组合,但没有进行检测的主要行是:

ReturnType<IPayloadObjectTypeMap[key]> extends Readonly<{ required: false }>

注意:我已经添加了一个| true| false到最后一个条件作为一种方式来测试条件的结果,我不能让它为真,在最后的代码中,我希望第一个扩展是undefined的并集,第二个没有并集,只有第一个类型。
打字机Playground

function required <Fn extends TransformHandler> (fn: Fn) {
  return Object.assign(fn, { required: true } as const)
}

function optional <Fn extends TransformHandler> (fn: Fn) {
  return Object.assign(fn, { required: false } as const)
}

type TransformHandler<Input = any, Output = any> = (input: Input) => Output
type TransformHandlerExtended<Input = any, Output = any> = TransformHandler<Input, Output> & { required: boolean }
type PayloadObjectTypeMap = { [key: string]: TransformHandlerExtended }
type ExtractPayload<IPayloadObjectTypeMap extends PayloadObjectTypeMap> = {
  [key in keyof IPayloadObjectTypeMap]: IPayloadObjectTypeMap[key] extends TransformHandler ? 
  ReturnType<IPayloadObjectTypeMap[key]> extends Readonly<{ required: false }>
      ? ReturnType<IPayloadObjectTypeMap[key]> | true
      : ReturnType<IPayloadObjectTypeMap[key]> | false
  : never
}

const p = {
  size: optional(v => parseInt(v)),
  shape: required(v => v + "")
}

type g = ExtractPayload<typeof p>
//  ^?
// should be { size: number | undefined, shape: string }
ffvjumwh

ffvjumwh1#

我检查的是返回类型而不是函数类型本身🤦

function required <Fn extends TransformHandler> (fn: Fn) {
  return Object.assign(fn, { required: true } as const)
}

function optional <Fn extends TransformHandler> (fn: Fn) {
  return Object.assign(fn, { required: false } as const)
}

type TransformHandler<Input = any, Output = any> = (input: Input) => Output
type TransformHandlerExtended<Input = any, Output = any, Required = boolean> =
  TransformHandler<Input, Output> &
  Readonly<{ required: Required }>
type PayloadObjectTypeMap = { [key: string]: TransformHandlerExtended }
type ExtractPayload<IPayloadObjectTypeMap extends PayloadObjectTypeMap> = {
  [key in keyof IPayloadObjectTypeMap]: IPayloadObjectTypeMap[key] extends TransformHandler ?
    IPayloadObjectTypeMap[key] extends Readonly<{ required: false }>
      ? ReturnType<IPayloadObjectTypeMap[key]> | undefined
      : ReturnType<IPayloadObjectTypeMap[key]>
  : never
}

const p = {
  size: optional(v => parseInt(v)),
  shape: required(v => v + "")
}

type g = ExtractPayload<typeof p>

相关问题