{"version":3,"file":"partial.mjs","sources":["../../src/record/partial.mts"],"sourcesContent":["import { expectType } from 'ts-data-forge';\nimport {\n  type ArrayElement,\n  type NonEmptyTuple,\n  type PartiallyPartial,\n  type TypeEq,\n  type UnknownRecord,\n} from 'ts-type-forge';\nimport {\n  type ExcessPropertyOption,\n  type Type,\n  type TypeOf,\n  type UnknownShape,\n  flattenShapeStructure,\n  hasRecordInternals,\n} from '../type.mjs';\nimport { toUnionKeyString } from '../utils/index.mjs';\nimport { optional } from './optional.mjs';\nimport { record } from './record.mjs';\n\n/**\n * Creates a Partial type. If keysToBeOptional is set, only those keys are\n * optional, otherwise, all properties are optional.\n */\nexport const partial = <\n  const R extends UnknownRecord,\n  const KeysToBeOptional extends NonEmptyTuple<keyof R & string>,\n>(\n  recordType: Type<R>,\n  options?: Partial<\n    Readonly<{\n      keysToBeOptional: KeysToBeOptional;\n      typeName: string;\n      excessProperty: ExcessPropertyOption;\n    }>\n  >,\n): PartialType<R, KeysToBeOptional> => {\n  if (!hasRecordInternals(recordType)) {\n    throw new Error(\n      `Expected a record type but received: ${recordType.typeName}`,\n    );\n  }\n\n  const shape = flattenShapeStructure(recordType.shapeStructure);\n\n  if (shape === undefined) {\n    throw new Error(\n      `partial() requires a simple or intersection record type, but received a union type`,\n    );\n  }\n\n  const typeNameFilled: string =\n    options?.typeName ??\n    (options?.keysToBeOptional === undefined\n      ? `Partial<${recordType.typeName}>`\n      : `PartiallyPartial<${recordType.typeName}, ${toUnionKeyString(options.keysToBeOptional)}>`);\n\n  const keysToBeOptional: ReadonlySet<string> = new Set(\n    options?.keysToBeOptional ?? Object.keys(shape),\n  );\n\n  const partialShape = Object.fromEntries(\n    Object.entries(shape).map(\n      ([k, v]) => [k, keysToBeOptional.has(k) ? optional(v) : v] as const,\n    ),\n  ) satisfies UnknownShape;\n\n  // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n  return record(partialShape, {\n    typeName: typeNameFilled,\n    excessProperty: options?.excessProperty ?? recordType.excessProperty,\n  }) as unknown as PartialType<R, KeysToBeOptional>;\n};\n\ntype PartialType<\n  R extends UnknownRecord,\n  KeysToBeOptional extends NonEmptyTuple<keyof R & string> | undefined =\n    undefined,\n> = Type<PartialValue<R, KeysToBeOptional>>;\n\n/** Compute the partial value type. */\ntype PartialValue<\n  R extends UnknownRecord,\n  KeysToBeOptional extends NonEmptyTuple<keyof R & string> | undefined,\n> =\n  TypeEq<KeysToBeOptional, undefined> extends true\n    ? Partial<R>\n    : PartiallyPartial<R, ArrayElement<KeysToBeOptional>>;\n\n// --- expectType assertions ---\n\n{\n  type Base = ReturnType<\n    typeof record<Readonly<{ a: Type<0>; b: Type<1>; c: Type<2> }>>\n  >;\n\n  expectType<\n    PartialType<TypeOf<Base>, readonly ['a', 'b', 'c']>,\n    Type<Partial<Readonly<{ a: 0; b: 1; c: 2 }>>>\n  >('=');\n\n  expectType<\n    PartialType<TypeOf<Base>, readonly ['a', 'b']>,\n    Type<Readonly<{ a?: 0; b?: 1; c: 2 }>>\n  >('=');\n\n  expectType<\n    // @ts-expect-error NonEmptyTuple is required if keysToBeOptional is provided\n    PartialType<TypeOf<Base>, readonly []>,\n    Type<Readonly<{ a?: 0; b?: 1; c: 2 }>>\n  >('!=');\n\n  expectType<\n    PartialType<TypeOf<Base>>,\n    Type<Readonly<{ a?: 0; b?: 1; c?: 2 }>>\n  >('=');\n\n  // partial with no keys makes all properties optional\n  expectType<\n    TypeOf<\n      ReturnType<typeof partial<TypeOf<Base>, NonEmptyTuple<'a' | 'b' | 'c'>>>\n    >,\n    Partial<Readonly<{ a: 0; b: 1; c: 2 }>>\n  >('=');\n}\n"],"names":[],"mappings":";;;;;;;MAwBa,OAAA,GAAU,CAIrB,UAAA,EACA,OAAA,KAOqC;AACrC,EAAA,IAAI,CAAC,kBAAA,CAAmB,UAAU,CAAA,EAAG;AACnC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,qCAAA,EAAwC,WAAW,QAAQ,CAAA;AAAA,KAC7D;AAAA,EAAA;AAGF,EAAA,MAAM,KAAA,GAAQ,qBAAA,CAAsB,UAAA,CAAW,cAAc,CAAA;AAE7D,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,kFAAA;AAAA,KACF;AAAA,EAAA;AAGF,EAAA,MAAM,iBACJ,OAAA,EAAS,QAAA,KACR,OAAA,EAAS,gBAAA,KAAqB,SAC3B,CAAA,QAAA,EAAW,UAAA,CAAW,QAAQ,CAAA,CAAA,CAAA,GAC9B,oBAAoB,UAAA,CAAW,QAAQ,KAAK,gBAAA,CAAiB,OAAA,CAAQ,gBAAgB,CAAC,CAAA,CAAA,CAAA,CAAA;AAE5F,EAAA,MAAM,mBAAwC,IAAI,GAAA;AAAA,IAChD,OAAA,EAAS,gBAAA,IAAoB,MAAA,CAAO,IAAA,CAAK,KAAK;AAAA,GAChD;AAEA,EAAA,MAAM,eAAe,MAAA,CAAO,WAAA;AAAA,IAC1B,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,CAAE,GAAA;AAAA,MACpB,CAAC,CAAC,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA,EAAG,gBAAA,CAAiB,GAAA,CAAI,CAAC,CAAA,GAAI,QAAA,CAAS,CAAC,IAAI,CAAC;AAAA;AAC3D,GACF;AAGA,EAAA,OAAO,OAAO,YAAA,EAAc;AAAA,IAC1B,QAAA,EAAU,cAAA;AAAA,IACV,cAAA,EAAgB,OAAA,EAAS,cAAA,IAAkB,UAAA,CAAW;AAAA,GACvD,CAAA;AACH;;;;"}