import type { IsTuple } from 'type-fest'; /** Keys of a tuple/array that are NOT inherited from `Array.prototype` (i.e. own element indices and custom declared keys). */ type TupleArrayPrototype = Type extends unknown[] ? Array : ReadonlyArray; type TupleOwnKey = Key extends number ? number extends Key ? never : Key : Key extends 'length' | keyof TupleArrayPrototype ? never : Key; type ArrayNumericOwnKey = Key extends keyof unknown[] ? Key extends number ? number extends Key ? never : Key : never : Key extends number | `${number}` ? Key : never; export type ArrayOwnKeys = IsTuple extends true ? keyof { [Key in keyof Type as TupleOwnKey]: unknown; } : keyof { [Key in keyof Type as ArrayNumericOwnKey]: unknown; }; /** Like `ArrayOwnKeys` but narrowed to `string | number` (excludes symbols). */ export type ArrayOwnStringKeys = Extract, string | number>; /** The string key union that `Object.entries()` would produce for a tuple/array. */ export type ArrayEntryKey = number extends Type['length'] ? `${number}` | `${ArrayOwnStringKeys}` : `${ArrayOwnStringKeys}`; /** The value union that `Object.entries()` / `Object.values()` would produce for a tuple/array. */ export type ArrayEntryValue = number extends Type['length'] ? Type[number] | Type[ArrayOwnStringKeys] : Type[ArrayOwnStringKeys]; type HasWidenedTemplateSegment = string extends Segment ? true : `${number}` extends Segment ? true : `${bigint}` extends Segment ? true : false; type HasWidenedStringKey = string extends Key ? true : Key extends `${infer Prefix}${infer Suffix}` ? HasWidenedTemplateSegment extends true ? true : HasWidenedTemplateSegment extends true ? true : false : false; export type HasWidenedKey = Key extends string ? HasWidenedStringKey extends true ? true : Extract extends never ? false : true : Key extends number ? number extends Key ? true : Extract extends never ? false : true : Key extends symbol ? symbol extends Key ? true : Extract extends never ? false : true : false; export type ObjectType = unknown extends Value ? object : Extract; type ObjectWithoutProperty = { [Property in keyof ObjectValue as Property extends Key ? never : Property]: ObjectValue[Property]; }; export type ObjectWithFallbackProperty = ObjectWithoutProperty & { [Property in Key]-?: unknown; }; export {};