import type { IsTuple, Simplify } from 'type-fest'; import type { ArrayOwnKeys, ArrayEntryKey, ArrayEntryValue } from './internal-types.js'; type OptionalMappedKeys = Simplify<{ -readonly [Key in Keys as `${Extract}`]?: NewValue; }>; type MappedArrayOwnValues = OptionalMappedKeys, NewValue>; type HasTupleIndex = Index extends ArrayOwnKeys ? true : `${Index}` extends ArrayOwnKeys ? true : false; type FixedTupleIndexKeys = HasTupleIndex extends true ? FixedTupleIndexKeys : Keys; type TupleStaticPart = number extends Type['length'] ? Type extends readonly [infer Head, ...infer Tail] ? TupleStaticPart : Result : Type; type TupleExtraKeys = number extends Type['length'] ? VariadicTupleExtraKeys : Extract, FixedTupleIndexKeys>, keyof Type>; type NumericTupleExtraKeys = Extract, number | `${number}`>; type MappedPlainTupleElement = number extends Extract ? NewValue : {} extends Pick ? NewValue | undefined : NewValue; type MappedPlainTupleValues = { -readonly [Key in keyof Type]: MappedPlainTupleElement; }; type NumericLiteralKeys = keyof { [Key in Extract, number> as number extends Key ? never : Key]: unknown; }; type VariadicTupleTupleKeys = FixedTupleIndexKeys> | NumericLiteralKeys; type VariadicTupleExtraKeys = Extract | keyof unknown[] | 'length'> | Exclude, VariadicTupleTupleKeys>, keyof Type>; type MappedTupleElement = {} extends Pick ? NewValue | undefined : NewValue; type MappedTupleIntersectionElements = HasTupleIndex extends true ? {} extends Pick ? Mapped | MappedTupleIntersectionElements]> : MappedTupleIntersectionElements]> : Mapped; type MappedFixedTupleBaseValues = TupleExtraKeys extends never ? undefined extends Type[number] ? MappedTupleIntersectionElements : MappedPlainTupleValues : MappedTupleIntersectionElements; type MappedTupleBaseValues = number extends Type['length'] ? TupleExtraKeys extends never ? MappedPlainTupleValues : [...MappedPlainTupleValues, NewValue>, ...NewValue[]] : MappedFixedTupleBaseValues; type MappedTupleValues = TupleExtraKeys extends never ? MappedTupleBaseValues : NumericTupleExtraKeys extends never ? MappedTupleBaseValues & OptionalMappedKeys, NewValue> : NewValue[] & OptionalMappedKeys, NewValue>; type MappedArrayValues = IsTuple extends true ? MappedTupleValues : NewValue[] & MappedArrayOwnValues; type IndexedCollectionElement = Type extends ArrayLike ? Element : never; type IndexedCollectionMappedValues = Partial>; type IsTypedArrayOrBuffer = Type extends readonly unknown[] ? false : Type extends ArrayBufferView ? Type extends DataView ? false : true : false; type NormalizeStrict = IsStrict extends false ? false : true; type ObjectSourceKeys = Extract; type HasFunctionValues = Extract], (...arguments_: never[]) => unknown> extends never ? false : true; type HasLooseObjectCallbackShape = Type extends Record ? HasFunctionValues extends true ? false : true : false; type LooseObjectCallbackKey = Type extends unknown ? HasLooseObjectCallbackShape extends true ? `${ObjectSourceKeys}` : string : never; type StrictObjectCallbackKey = Type extends unknown ? Type extends Record ? `${ObjectSourceKeys}` : string : never; type LooseObjectCallbackValue = Type extends unknown ? HasLooseObjectCallbackShape extends true ? Type[ObjectSourceKeys] : unknown : never; type StrictObjectCallbackValue = Type extends unknown ? Type extends Record ? Type[ObjectSourceKeys] : unknown : never; type StrictObjectMappedValues = Type extends Record ? Simplify}`]: NewValue; }>> : Partial>; type ObjectMappedValues = StrictObjectMappedValues; type MapFunctionKey = Type extends unknown ? Type extends readonly unknown[] ? ArrayEntryKey : IsTypedArrayOrBuffer extends true ? `${number}` : IsStrict extends true ? StrictObjectCallbackKey : LooseObjectCallbackKey : never; type MapFunctionValue = Type extends unknown ? Type extends readonly unknown[] ? ArrayEntryValue : IsTypedArrayOrBuffer extends true ? IndexedCollectionElement : IsStrict extends true ? StrictObjectCallbackValue : LooseObjectCallbackValue : never; type MappedValues = Type extends readonly unknown[] ? MappedArrayValues : IsTypedArrayOrBuffer extends true ? IndexedCollectionMappedValues : ObjectMappedValues; /** A strongly-typed version of mapping over an object's values, preserving keys. This avoids the common footgun where `objectFromEntries(objectKeys(obj).map(…))` produces optional keys because `.map()` returns a dynamic-length array. For non-array objects, strict mode is the default and keeps the result conservative: declared keys become optional because TypeScript cannot know whether a property is an own enumerable property from static shape alone. Pass `{strict: false}` to use the data-object callback path for plain shapes without function-valued members. The non-array object result still stays conservative in both modes, including for interface, class, and structural aliases, because `Object.entries()` only returns own enumerable properties. Array inputs follow `Object.entries()` semantics for elements: only present enumerable elements are mapped, so sparse holes are skipped at runtime. For non-tuple arrays, the types intentionally use a dense array model and do not try to represent sparse holes or far numeric writes precisely; only numeric entries are reflected in the types, and named custom properties on arrays are treated as unsupported. For tuple inputs, named extra keys are preserved when they do not shadow existing array members, but they stay optional in the result because static types cannot prove those properties are enumerable. Numeric extra keys are a widening boundary and produce array results instead of tuple-preserving ones. Typed arrays and `Buffer` are typed as numeric indexed collections too, but their mapped result stays a plain object with numeric keys because that matches the current runtime implementation. @example ``` import {objectMapValues} from 'ts-extras'; const object = {a: 1, b: 2, c: 3}; const mapped = objectMapValues(object, value => String(value)); //=> {a?: string; b?: string; c?: string} objectMapValues(object, (value, key) => { value satisfies 1 | 2 | 3; key satisfies 'a' | 'b' | 'c'; return String(value); }, {strict: false}); ``` @category Improved builtin */ export declare function objectMapValues(object: Type, mapFunction: (value: MapFunctionValue>, key: MapFunctionKey>) => NewValue, options?: { strict?: IsStrict; }): MappedValues>; export {};