+978
-3
@@ -1,4 +0,59 @@ | ||
| import { StandardSchemaV1 } from "@standard-schema/spec"; | ||
| import { If, IsAny, IsNever, Merge, OptionalKeysOf, RequiredKeysOf, SetRequired, Simplify } from "type-fest"; | ||
| //#region ../../node_modules/.pnpm/@standard-schema+spec@1.0.0/node_modules/@standard-schema/spec/dist/index.d.ts | ||
| /** The Standard Schema interface. */ | ||
| interface StandardSchemaV1<Input = unknown, Output = Input> { | ||
| /** The Standard Schema properties. */ | ||
| readonly "~standard": StandardSchemaV1.Props<Input, Output>; | ||
| } | ||
| declare namespace StandardSchemaV1 { | ||
| /** The Standard Schema properties interface. */ | ||
| export interface Props<Input = unknown, Output = Input> { | ||
| /** The version number of the standard. */ | ||
| readonly version: 1; | ||
| /** The vendor name of the schema library. */ | ||
| readonly vendor: string; | ||
| /** Validates unknown input values. */ | ||
| readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>; | ||
| /** Inferred types associated with the schema. */ | ||
| readonly types?: Types<Input, Output> | undefined; | ||
| } | ||
| /** The result interface of the validate function. */ | ||
| export type Result<Output> = SuccessResult<Output> | FailureResult; | ||
| /** The result interface if validation succeeds. */ | ||
| export interface SuccessResult<Output> { | ||
| /** The typed output value. */ | ||
| readonly value: Output; | ||
| /** The non-existent issues. */ | ||
| readonly issues?: undefined; | ||
| } | ||
| /** The result interface if validation fails. */ | ||
| export interface FailureResult { | ||
| /** The issues of failed validation. */ | ||
| readonly issues: ReadonlyArray<Issue>; | ||
| } | ||
| /** The issue interface of the failure output. */ | ||
| export interface Issue { | ||
| /** The error message of the issue. */ | ||
| readonly message: string; | ||
| /** The path of the issue, if any. */ | ||
| readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined; | ||
| } | ||
| /** The path segment interface of the issue. */ | ||
| export interface PathSegment { | ||
| /** The key representing a path segment. */ | ||
| readonly key: PropertyKey; | ||
| } | ||
| /** The Standard Schema types interface. */ | ||
| export interface Types<Input = unknown, Output = Input> { | ||
| /** The input type of the schema. */ | ||
| readonly input: Input; | ||
| /** The output type of the schema. */ | ||
| readonly output: Output; | ||
| } | ||
| /** Infers the input type of a Standard Schema. */ | ||
| export type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["input"]; | ||
| /** Infers the output type of a Standard Schema. */ | ||
| export type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["output"]; | ||
| export {}; | ||
| } | ||
| //#endregion | ||
| //#region src/types/field/raw.d.ts | ||
@@ -49,2 +104,922 @@ type OptionalKeys<T> = { [K in keyof T]-?: undefined extends T[K] ? K : never }[keyof T]; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/union-to-intersection.d.ts | ||
| /** | ||
| Convert a union type to an intersection type using [distributive conditional types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types). | ||
| Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153). | ||
| @example | ||
| ``` | ||
| import type {UnionToIntersection} from 'type-fest'; | ||
| type Union = {the(): void} | {great(arg: string): void} | {escape: boolean}; | ||
| type Intersection = UnionToIntersection<Union>; | ||
| //=> {the(): void; great(arg: string): void; escape: boolean}; | ||
| ``` | ||
| @category Type | ||
| */ | ||
| type UnionToIntersection$1<Union> = ( | ||
| // `extends unknown` is always going to be the case and is used to convert the | ||
| // `Union` into a [distributive conditional | ||
| // type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types). | ||
| Union extends unknown | ||
| // The union type is used as the only argument to a function since the union | ||
| // of function arguments is an intersection. | ||
| ? (distributedUnion: Union) => void | ||
| // This won't happen. | ||
| : never | ||
| // Infer the `Intersection` type since TypeScript represents the positional | ||
| // arguments of unions of functions as an intersection of the union. | ||
| ) extends ((mergedIntersection: infer Intersection) => void) | ||
| // The `& Union` is to ensure result of `UnionToIntersection<A | B>` is always assignable to `A | B` | ||
| ? Intersection & Union : never; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/keys-of-union.d.ts | ||
| /** | ||
| Create a union of all keys from a given type, even those exclusive to specific union members. | ||
| Unlike the native `keyof` keyword, which returns keys present in **all** union members, this type returns keys from **any** member. | ||
| @link https://stackoverflow.com/a/49402091 | ||
| @example | ||
| ``` | ||
| import type {KeysOfUnion} from 'type-fest'; | ||
| type A = { | ||
| common: string; | ||
| a: number; | ||
| }; | ||
| type B = { | ||
| common: string; | ||
| b: string; | ||
| }; | ||
| type C = { | ||
| common: string; | ||
| c: boolean; | ||
| }; | ||
| type Union = A | B | C; | ||
| type CommonKeys = keyof Union; | ||
| //=> 'common' | ||
| type AllKeys = KeysOfUnion<Union>; | ||
| //=> 'common' | 'a' | 'b' | 'c' | ||
| ``` | ||
| @category Object | ||
| */ | ||
| type KeysOfUnion<ObjectType> = | ||
| // Hack to fix https://github.com/sindresorhus/type-fest/issues/1008 | ||
| keyof UnionToIntersection$1<ObjectType extends unknown ? Record<keyof ObjectType, never> : never>; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/is-any.d.ts | ||
| /** | ||
| Returns a boolean for whether the given type is `any`. | ||
| @link https://stackoverflow.com/a/49928360/1490091 | ||
| Useful in type utilities, such as disallowing `any`s to be passed to a function. | ||
| @example | ||
| ``` | ||
| import type {IsAny} from 'type-fest'; | ||
| const typedObject = {a: 1, b: 2} as const; | ||
| const anyObject: any = {a: 1, b: 2}; | ||
| function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(object: O, key: K) { | ||
| return object[key]; | ||
| } | ||
| const typedA = get(typedObject, 'a'); | ||
| //=> 1 | ||
| const anyA = get(anyObject, 'a'); | ||
| //=> any | ||
| ``` | ||
| @category Type Guard | ||
| @category Utilities | ||
| */ | ||
| type IsAny<T> = 0 extends 1 & NoInfer<T> ? true : false; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/is-optional-key-of.d.ts | ||
| /** | ||
| Returns a boolean for whether the given key is an optional key of type. | ||
| This is useful when writing utility types or schema validators that need to differentiate `optional` keys. | ||
| @example | ||
| ``` | ||
| import type {IsOptionalKeyOf} from 'type-fest'; | ||
| type User = { | ||
| name: string; | ||
| surname: string; | ||
| luckyNumber?: number; | ||
| }; | ||
| type Admin = { | ||
| name: string; | ||
| surname?: string; | ||
| }; | ||
| type T1 = IsOptionalKeyOf<User, 'luckyNumber'>; | ||
| //=> true | ||
| type T2 = IsOptionalKeyOf<User, 'name'>; | ||
| //=> false | ||
| type T3 = IsOptionalKeyOf<User, 'name' | 'luckyNumber'>; | ||
| //=> boolean | ||
| type T4 = IsOptionalKeyOf<User | Admin, 'name'>; | ||
| //=> false | ||
| type T5 = IsOptionalKeyOf<User | Admin, 'surname'>; | ||
| //=> boolean | ||
| ``` | ||
| @category Type Guard | ||
| @category Utilities | ||
| */ | ||
| type IsOptionalKeyOf<Type extends object, Key$1 extends keyof Type> = IsAny<Type | Key$1> extends true ? never : Key$1 extends keyof Type ? Type extends Record<Key$1, Type[Key$1]> ? false : true : false; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/optional-keys-of.d.ts | ||
| /** | ||
| Extract all optional keys from the given type. | ||
| This is useful when you want to create a new type that contains different type values for the optional keys only. | ||
| @example | ||
| ``` | ||
| import type {OptionalKeysOf, Except} from 'type-fest'; | ||
| type User = { | ||
| name: string; | ||
| surname: string; | ||
| luckyNumber?: number; | ||
| }; | ||
| const REMOVE_FIELD = Symbol('remove field symbol'); | ||
| type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKeysOf<Entity>> & { | ||
| [Key in OptionalKeysOf<Entity>]?: Entity[Key] | typeof REMOVE_FIELD; | ||
| }; | ||
| const update1: UpdateOperation<User> = { | ||
| name: 'Alice', | ||
| }; | ||
| const update2: UpdateOperation<User> = { | ||
| name: 'Bob', | ||
| luckyNumber: REMOVE_FIELD, | ||
| }; | ||
| ``` | ||
| @category Utilities | ||
| */ | ||
| type OptionalKeysOf<Type extends object> = Type extends unknown // For distributing `Type` | ||
| ? (keyof { [Key in keyof Type as IsOptionalKeyOf<Type, Key> extends false ? never : Key]: never }) & keyof Type // Intersect with `keyof Type` to ensure result of `OptionalKeysOf<Type>` is always assignable to `keyof Type` | ||
| : never; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/required-keys-of.d.ts | ||
| /** | ||
| Extract all required keys from the given type. | ||
| This is useful when you want to create a new type that contains different type values for the required keys only or use the list of keys for validation purposes, etc... | ||
| @example | ||
| ``` | ||
| import type {RequiredKeysOf} from 'type-fest'; | ||
| declare function createValidation< | ||
| Entity extends object, | ||
| Key extends RequiredKeysOf<Entity> = RequiredKeysOf<Entity>, | ||
| >(field: Key, validator: (value: Entity[Key]) => boolean): (entity: Entity) => boolean; | ||
| type User = { | ||
| name: string; | ||
| surname: string; | ||
| luckyNumber?: number; | ||
| }; | ||
| const validator1 = createValidation<User>('name', value => value.length < 25); | ||
| const validator2 = createValidation<User>('surname', value => value.length < 25); | ||
| // @ts-expect-error | ||
| const validator3 = createValidation<User>('luckyNumber', value => value > 0); | ||
| // Error: Argument of type '"luckyNumber"' is not assignable to parameter of type '"name" | "surname"'. | ||
| ``` | ||
| @category Utilities | ||
| */ | ||
| type RequiredKeysOf<Type extends object> = Type extends unknown // For distributing `Type` | ||
| ? Exclude<keyof Type, OptionalKeysOf<Type>> : never; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/is-never.d.ts | ||
| /** | ||
| Returns a boolean for whether the given type is `never`. | ||
| @link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919 | ||
| @link https://stackoverflow.com/a/53984913/10292952 | ||
| @link https://www.zhenghao.io/posts/ts-never | ||
| Useful in type utilities, such as checking if something does not occur. | ||
| @example | ||
| ``` | ||
| import type {IsNever, And} from 'type-fest'; | ||
| type A = IsNever<never>; | ||
| //=> true | ||
| type B = IsNever<any>; | ||
| //=> false | ||
| type C = IsNever<unknown>; | ||
| //=> false | ||
| type D = IsNever<never[]>; | ||
| //=> false | ||
| type E = IsNever<object>; | ||
| //=> false | ||
| type F = IsNever<string>; | ||
| //=> false | ||
| ``` | ||
| @example | ||
| ``` | ||
| import type {IsNever} from 'type-fest'; | ||
| type IsTrue<T> = T extends true ? true : false; | ||
| // When a distributive conditional is instantiated with `never`, the entire conditional results in `never`. | ||
| type A = IsTrue<never>; | ||
| // ^? type A = never | ||
| // If you don't want that behaviour, you can explicitly add an `IsNever` check before the distributive conditional. | ||
| type IsTrueFixed<T> = | ||
| IsNever<T> extends true ? false : T extends true ? true : false; | ||
| type B = IsTrueFixed<never>; | ||
| // ^? type B = false | ||
| ``` | ||
| @category Type Guard | ||
| @category Utilities | ||
| */ | ||
| type IsNever<T> = [T] extends [never] ? true : false; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/if.d.ts | ||
| /** | ||
| An if-else-like type that resolves depending on whether the given `boolean` type is `true` or `false`. | ||
| Use-cases: | ||
| - You can use this in combination with `Is*` types to create an if-else-like experience. For example, `If<IsAny<any>, 'is any', 'not any'>`. | ||
| Note: | ||
| - Returns a union of if branch and else branch if the given type is `boolean` or `any`. For example, `If<boolean, 'Y', 'N'>` will return `'Y' | 'N'`. | ||
| - Returns the else branch if the given type is `never`. For example, `If<never, 'Y', 'N'>` will return `'N'`. | ||
| @example | ||
| ``` | ||
| import type {If} from 'type-fest'; | ||
| type A = If<true, 'yes', 'no'>; | ||
| //=> 'yes' | ||
| type B = If<false, 'yes', 'no'>; | ||
| //=> 'no' | ||
| type C = If<boolean, 'yes', 'no'>; | ||
| //=> 'yes' | 'no' | ||
| type D = If<any, 'yes', 'no'>; | ||
| //=> 'yes' | 'no' | ||
| type E = If<never, 'yes', 'no'>; | ||
| //=> 'no' | ||
| ``` | ||
| @example | ||
| ``` | ||
| import type {If, IsAny, IsNever} from 'type-fest'; | ||
| type A = If<IsAny<unknown>, 'is any', 'not any'>; | ||
| //=> 'not any' | ||
| type B = If<IsNever<never>, 'is never', 'not never'>; | ||
| //=> 'is never' | ||
| ``` | ||
| @example | ||
| ``` | ||
| import type {If, IsEqual} from 'type-fest'; | ||
| type IfEqual<T, U, IfBranch, ElseBranch> = If<IsEqual<T, U>, IfBranch, ElseBranch>; | ||
| type A = IfEqual<string, string, 'equal', 'not equal'>; | ||
| //=> 'equal' | ||
| type B = IfEqual<string, number, 'equal', 'not equal'>; | ||
| //=> 'not equal' | ||
| ``` | ||
| Note: Sometimes using the `If` type can make an implementation non–tail-recursive, which can impact performance. In such cases, it’s better to use a conditional directly. Refer to the following example: | ||
| @example | ||
| ``` | ||
| import type {If, IsEqual, StringRepeat} from 'type-fest'; | ||
| type HundredZeroes = StringRepeat<'0', 100>; | ||
| // The following implementation is not tail recursive | ||
| type Includes<S extends string, Char extends string> = | ||
| S extends `${infer First}${infer Rest}` | ||
| ? If<IsEqual<First, Char>, | ||
| 'found', | ||
| Includes<Rest, Char>> | ||
| : 'not found'; | ||
| // Hence, instantiations with long strings will fail | ||
| // @ts-expect-error | ||
| type Fails = Includes<HundredZeroes, '1'>; | ||
| // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| // Error: Type instantiation is excessively deep and possibly infinite. | ||
| // However, if we use a simple conditional instead of `If`, the implementation becomes tail-recursive | ||
| type IncludesWithoutIf<S extends string, Char extends string> = | ||
| S extends `${infer First}${infer Rest}` | ||
| ? IsEqual<First, Char> extends true | ||
| ? 'found' | ||
| : IncludesWithoutIf<Rest, Char> | ||
| : 'not found'; | ||
| // Now, instantiations with long strings will work | ||
| type Works = IncludesWithoutIf<HundredZeroes, '1'>; | ||
| //=> 'not found' | ||
| ``` | ||
| @category Type Guard | ||
| @category Utilities | ||
| */ | ||
| type If<Type extends boolean, IfBranch, ElseBranch> = IsNever<Type> extends true ? ElseBranch : Type extends true ? IfBranch : ElseBranch; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/unknown-array.d.ts | ||
| /** | ||
| Represents an array with `unknown` value. | ||
| Use case: You want a type that all arrays can be assigned to, but you don't care about the value. | ||
| @example | ||
| ``` | ||
| import type {UnknownArray} from 'type-fest'; | ||
| type IsArray<T> = T extends UnknownArray ? true : false; | ||
| type A = IsArray<['foo']>; | ||
| //=> true | ||
| type B = IsArray<readonly number[]>; | ||
| //=> true | ||
| type C = IsArray<string>; | ||
| //=> false | ||
| ``` | ||
| @category Type | ||
| @category Array | ||
| */ | ||
| type UnknownArray = readonly unknown[]; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/internal/array.d.ts | ||
| /** | ||
| Returns whether the given array `T` is readonly. | ||
| */ | ||
| type IsArrayReadonly<T extends UnknownArray> = If<IsNever<T>, false, T extends unknown[] ? false : true>; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/simplify.d.ts | ||
| /** | ||
| Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability. | ||
| @example | ||
| ``` | ||
| import type {Simplify} from 'type-fest'; | ||
| type PositionProps = { | ||
| top: number; | ||
| left: number; | ||
| }; | ||
| type SizeProps = { | ||
| width: number; | ||
| height: number; | ||
| }; | ||
| // In your editor, hovering over `Props` will show a flattened object with all the properties. | ||
| type Props = Simplify<PositionProps & SizeProps>; | ||
| ``` | ||
| Sometimes it is desired to pass a value as a function argument that has a different type. At first inspection it may seem assignable, and then you discover it is not because the `value`'s type definition was defined as an interface. In the following example, `fn` requires an argument of type `Record<string, unknown>`. If the value is defined as a literal, then it is assignable. And if the `value` is defined as type using the `Simplify` utility the value is assignable. But if the `value` is defined as an interface, it is not assignable because the interface is not sealed and elsewhere a non-string property could be added to the interface. | ||
| If the type definition must be an interface (perhaps it was defined in a third-party npm package), then the `value` can be defined as `const value: Simplify<SomeInterface> = ...`. Then `value` will be assignable to the `fn` argument. Or the `value` can be cast as `Simplify<SomeInterface>` if you can't re-declare the `value`. | ||
| @example | ||
| ``` | ||
| import type {Simplify} from 'type-fest'; | ||
| interface SomeInterface { | ||
| foo: number; | ||
| bar?: string; | ||
| baz: number | undefined; | ||
| } | ||
| type SomeType = { | ||
| foo: number; | ||
| bar?: string; | ||
| baz: number | undefined; | ||
| }; | ||
| const literal = {foo: 123, bar: 'hello', baz: 456}; | ||
| const someType: SomeType = literal; | ||
| const someInterface: SomeInterface = literal; | ||
| declare function fn(object: Record<string, unknown>): void; | ||
| fn(literal); // Good: literal object type is sealed | ||
| fn(someType); // Good: type is sealed | ||
| // @ts-expect-error | ||
| fn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened | ||
| fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface` into a `type` | ||
| ``` | ||
| @link https://github.com/microsoft/TypeScript/issues/15300 | ||
| @see {@link SimplifyDeep} | ||
| @category Object | ||
| */ | ||
| type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {}; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/is-equal.d.ts | ||
| /** | ||
| Returns a boolean for whether the two given types are equal. | ||
| @link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650 | ||
| @link https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796 | ||
| Use-cases: | ||
| - If you want to make a conditional branch based on the result of a comparison of two types. | ||
| @example | ||
| ``` | ||
| import type {IsEqual} from 'type-fest'; | ||
| // This type returns a boolean for whether the given array includes the given item. | ||
| // `IsEqual` is used to compare the given array at position 0 and the given item and then return true if they are equal. | ||
| type Includes<Value extends readonly any[], Item> = | ||
| Value extends readonly [Value[0], ...infer rest] | ||
| ? IsEqual<Value[0], Item> extends true | ||
| ? true | ||
| : Includes<rest, Item> | ||
| : false; | ||
| ``` | ||
| @category Type Guard | ||
| @category Utilities | ||
| */ | ||
| type IsEqual<A, B> = [A] extends [B] ? [B] extends [A] ? _IsEqual<A, B> : false : false; | ||
| // This version fails the `equalWrappedTupleIntersectionToBeNeverAndNeverExpanded` test in `test-d/is-equal.ts`. | ||
| type _IsEqual<A, B> = (<G>() => G extends A & G | G ? 1 : 2) extends (<G>() => G extends B & G | G ? 1 : 2) ? true : false; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/omit-index-signature.d.ts | ||
| /** | ||
| Omit any index signatures from the given object type, leaving only explicitly defined properties. | ||
| This is the counterpart of `PickIndexSignature`. | ||
| Use-cases: | ||
| - Remove overly permissive signatures from third-party types. | ||
| This type was taken from this [StackOverflow answer](https://stackoverflow.com/a/68261113/420747). | ||
| It relies on the fact that an empty object (`{}`) is assignable to an object with just an index signature, like `Record<string, unknown>`, but not to an object with explicitly defined keys, like `Record<'foo' | 'bar', unknown>`. | ||
| (The actual value type, `unknown`, is irrelevant and could be any type. Only the key type matters.) | ||
| ``` | ||
| const indexed: Record<string, unknown> = {}; // Allowed | ||
| // @ts-expect-error | ||
| const keyed: Record<'foo', unknown> = {}; // Error | ||
| // => TS2739: Type '{}' is missing the following properties from type 'Record<"foo" | "bar", unknown>': foo, bar | ||
| ``` | ||
| Instead of causing a type error like the above, you can also use a [conditional type](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html) to test whether a type is assignable to another: | ||
| ``` | ||
| type Indexed = {} extends Record<string, unknown> | ||
| ? '✅ `{}` is assignable to `Record<string, unknown>`' | ||
| : '❌ `{}` is NOT assignable to `Record<string, unknown>`'; | ||
| // => '✅ `{}` is assignable to `Record<string, unknown>`' | ||
| type Keyed = {} extends Record<'foo' | 'bar', unknown> | ||
| ? '✅ `{}` is assignable to `Record<\'foo\' | \'bar\', unknown>`' | ||
| : '❌ `{}` is NOT assignable to `Record<\'foo\' | \'bar\', unknown>`'; | ||
| // => "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`" | ||
| ``` | ||
| Using a [mapped type](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#further-exploration), you can then check for each `KeyType` of `ObjectType`... | ||
| ``` | ||
| type OmitIndexSignature<ObjectType> = { | ||
| [KeyType in keyof ObjectType // Map each key of `ObjectType`... | ||
| ]: ObjectType[KeyType]; // ...to its original value, i.e. `OmitIndexSignature<Foo> == Foo`. | ||
| }; | ||
| ``` | ||
| ...whether an empty object (`{}`) would be assignable to an object with that `KeyType` (`Record<KeyType, unknown>`)... | ||
| ``` | ||
| type OmitIndexSignature<ObjectType> = { | ||
| [KeyType in keyof ObjectType | ||
| // Is `{}` assignable to `Record<KeyType, unknown>`? | ||
| as {} extends Record<KeyType, unknown> | ||
| ? never // ✅ `{}` is assignable to `Record<KeyType, unknown>` | ||
| : KeyType // ❌ `{}` is NOT assignable to `Record<KeyType, unknown>` | ||
| ]: ObjectType[KeyType]; | ||
| }; | ||
| ``` | ||
| If `{}` is assignable, it means that `KeyType` is an index signature and we want to remove it. If it is not assignable, `KeyType` is a "real" key and we want to keep it. | ||
| @example | ||
| ``` | ||
| import type {OmitIndexSignature} from 'type-fest'; | ||
| type Example = { | ||
| // These index signatures will be removed. | ||
| [x: string]: any; | ||
| [x: number]: any; | ||
| [x: symbol]: any; | ||
| [x: `head-${string}`]: string; | ||
| [x: `${string}-tail`]: string; | ||
| [x: `head-${string}-tail`]: string; | ||
| [x: `${bigint}`]: string; | ||
| [x: `embedded-${number}`]: string; | ||
| // These explicitly defined keys will remain. | ||
| foo: 'bar'; | ||
| qux?: 'baz'; | ||
| }; | ||
| type ExampleWithoutIndexSignatures = OmitIndexSignature<Example>; | ||
| // => { foo: 'bar'; qux?: 'baz' | undefined; } | ||
| ``` | ||
| @see {@link PickIndexSignature} | ||
| @category Object | ||
| */ | ||
| type OmitIndexSignature<ObjectType> = { [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? never : KeyType]: ObjectType[KeyType] }; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/pick-index-signature.d.ts | ||
| /** | ||
| Pick only index signatures from the given object type, leaving out all explicitly defined properties. | ||
| This is the counterpart of `OmitIndexSignature`. | ||
| @example | ||
| ``` | ||
| import type {PickIndexSignature} from 'type-fest'; | ||
| declare const symbolKey: unique symbol; | ||
| type Example = { | ||
| // These index signatures will remain. | ||
| [x: string]: unknown; | ||
| [x: number]: unknown; | ||
| [x: symbol]: unknown; | ||
| [x: `head-${string}`]: string; | ||
| [x: `${string}-tail`]: string; | ||
| [x: `head-${string}-tail`]: string; | ||
| [x: `${bigint}`]: string; | ||
| [x: `embedded-${number}`]: string; | ||
| // These explicitly defined keys will be removed. | ||
| ['kebab-case-key']: string; | ||
| [symbolKey]: string; | ||
| foo: 'bar'; | ||
| qux?: 'baz'; | ||
| }; | ||
| type ExampleIndexSignature = PickIndexSignature<Example>; | ||
| // { | ||
| // [x: string]: unknown; | ||
| // [x: number]: unknown; | ||
| // [x: symbol]: unknown; | ||
| // [x: `head-${string}`]: string; | ||
| // [x: `${string}-tail`]: string; | ||
| // [x: `head-${string}-tail`]: string; | ||
| // [x: `${bigint}`]: string; | ||
| // [x: `embedded-${number}`]: string; | ||
| // } | ||
| ``` | ||
| @see {@link OmitIndexSignature} | ||
| @category Object | ||
| */ | ||
| type PickIndexSignature<ObjectType> = { [KeyType in keyof ObjectType as {} extends Record<KeyType, unknown> ? KeyType : never]: ObjectType[KeyType] }; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/merge.d.ts | ||
| // Merges two objects without worrying about index signatures. | ||
| type SimpleMerge<Destination, Source> = { [Key in keyof Destination as Key extends keyof Source ? never : Key]: Destination[Key] } & Source; | ||
| /** | ||
| Merge two types into a new type. Keys of the second type overrides keys of the first type. | ||
| @example | ||
| ``` | ||
| import type {Merge} from 'type-fest'; | ||
| type Foo = { | ||
| [x: string]: unknown; | ||
| [x: number]: unknown; | ||
| foo: string; | ||
| bar: symbol; | ||
| }; | ||
| type Bar = { | ||
| [x: number]: number; | ||
| [x: symbol]: unknown; | ||
| bar: Date; | ||
| baz: boolean; | ||
| }; | ||
| export type FooBar = Merge<Foo, Bar>; | ||
| // => { | ||
| // [x: string]: unknown; | ||
| // [x: number]: number; | ||
| // [x: symbol]: unknown; | ||
| // foo: string; | ||
| // bar: Date; | ||
| // baz: boolean; | ||
| // } | ||
| ``` | ||
| @category Object | ||
| */ | ||
| type Merge<Destination, Source> = Simplify<SimpleMerge<PickIndexSignature<Destination>, PickIndexSignature<Source>> & SimpleMerge<OmitIndexSignature<Destination>, OmitIndexSignature<Source>>>; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/internal/object.d.ts | ||
| /** | ||
| Works similar to the built-in `Pick` utility type, except for the following differences: | ||
| - Distributes over union types and allows picking keys from any member of the union type. | ||
| - Primitives types are returned as-is. | ||
| - Picks all keys if `Keys` is `any`. | ||
| - Doesn't pick `number` from a `string` index signature. | ||
| @example | ||
| ``` | ||
| type ImageUpload = { | ||
| url: string; | ||
| size: number; | ||
| thumbnailUrl: string; | ||
| }; | ||
| type VideoUpload = { | ||
| url: string; | ||
| duration: number; | ||
| encodingFormat: string; | ||
| }; | ||
| // Distributes over union types and allows picking keys from any member of the union type | ||
| type MediaDisplay = HomomorphicPick<ImageUpload | VideoUpload, "url" | "size" | "duration">; | ||
| //=> {url: string; size: number} | {url: string; duration: number} | ||
| // Primitive types are returned as-is | ||
| type Primitive = HomomorphicPick<string | number, 'toUpperCase' | 'toString'>; | ||
| //=> string | number | ||
| // Picks all keys if `Keys` is `any` | ||
| type Any = HomomorphicPick<{a: 1; b: 2} | {c: 3}, any>; | ||
| //=> {a: 1; b: 2} | {c: 3} | ||
| // Doesn't pick `number` from a `string` index signature | ||
| type IndexSignature = HomomorphicPick<{[k: string]: unknown}, number>; | ||
| //=> {} | ||
| */ | ||
| type HomomorphicPick<T, Keys extends KeysOfUnion<T>> = { [P in keyof T as Extract<P, Keys>]: T[P] }; | ||
| /** | ||
| Merges user specified options with default options. | ||
| @example | ||
| ``` | ||
| type PathsOptions = {maxRecursionDepth?: number; leavesOnly?: boolean}; | ||
| type DefaultPathsOptions = {maxRecursionDepth: 10; leavesOnly: false}; | ||
| type SpecifiedOptions = {leavesOnly: true}; | ||
| type Result = ApplyDefaultOptions<PathsOptions, DefaultPathsOptions, SpecifiedOptions>; | ||
| //=> {maxRecursionDepth: 10; leavesOnly: true} | ||
| ``` | ||
| @example | ||
| ``` | ||
| // Complains if default values are not provided for optional options | ||
| type PathsOptions = {maxRecursionDepth?: number; leavesOnly?: boolean}; | ||
| type DefaultPathsOptions = {maxRecursionDepth: 10}; | ||
| type SpecifiedOptions = {}; | ||
| type Result = ApplyDefaultOptions<PathsOptions, DefaultPathsOptions, SpecifiedOptions>; | ||
| // ~~~~~~~~~~~~~~~~~~~ | ||
| // Property 'leavesOnly' is missing in type 'DefaultPathsOptions' but required in type '{ maxRecursionDepth: number; leavesOnly: boolean; }'. | ||
| ``` | ||
| @example | ||
| ``` | ||
| // Complains if an option's default type does not conform to the expected type | ||
| type PathsOptions = {maxRecursionDepth?: number; leavesOnly?: boolean}; | ||
| type DefaultPathsOptions = {maxRecursionDepth: 10; leavesOnly: 'no'}; | ||
| type SpecifiedOptions = {}; | ||
| type Result = ApplyDefaultOptions<PathsOptions, DefaultPathsOptions, SpecifiedOptions>; | ||
| // ~~~~~~~~~~~~~~~~~~~ | ||
| // Types of property 'leavesOnly' are incompatible. Type 'string' is not assignable to type 'boolean'. | ||
| ``` | ||
| @example | ||
| ``` | ||
| // Complains if an option's specified type does not conform to the expected type | ||
| type PathsOptions = {maxRecursionDepth?: number; leavesOnly?: boolean}; | ||
| type DefaultPathsOptions = {maxRecursionDepth: 10; leavesOnly: false}; | ||
| type SpecifiedOptions = {leavesOnly: 'yes'}; | ||
| type Result = ApplyDefaultOptions<PathsOptions, DefaultPathsOptions, SpecifiedOptions>; | ||
| // ~~~~~~~~~~~~~~~~ | ||
| // Types of property 'leavesOnly' are incompatible. Type 'string' is not assignable to type 'boolean'. | ||
| ``` | ||
| */ | ||
| type ApplyDefaultOptions$1<Options extends object, Defaults extends Simplify<Omit<Required<Options>, RequiredKeysOf<Options>> & Partial<Record<RequiredKeysOf<Options>, never>>>, SpecifiedOptions extends Options> = If<IsAny<SpecifiedOptions>, Defaults, If<IsNever<SpecifiedOptions>, Defaults, Simplify<Merge<Defaults, { [Key in keyof SpecifiedOptions as Key extends OptionalKeysOf<Options> ? undefined extends SpecifiedOptions[Key] ? never : Key : Key]: SpecifiedOptions[Key] }> & Required<Options>>>>; | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/except.d.ts | ||
| /** | ||
| Filter out keys from an object. | ||
| Returns `never` if `Exclude` is strictly equal to `Key`. | ||
| Returns `never` if `Key` extends `Exclude`. | ||
| Returns `Key` otherwise. | ||
| @example | ||
| ``` | ||
| type Filtered = Filter<'foo', 'foo'>; | ||
| //=> never | ||
| ``` | ||
| @example | ||
| ``` | ||
| type Filtered = Filter<'bar', string>; | ||
| //=> never | ||
| ``` | ||
| @example | ||
| ``` | ||
| type Filtered = Filter<'bar', 'foo'>; | ||
| //=> 'bar' | ||
| ``` | ||
| @see {Except} | ||
| */ | ||
| type Filter<KeyType$1, ExcludeType> = IsEqual<KeyType$1, ExcludeType> extends true ? never : (KeyType$1 extends ExcludeType ? never : KeyType$1); | ||
| type ExceptOptions = { | ||
| /** | ||
| Disallow assigning non-specified properties. | ||
| Note that any omitted properties in the resulting type will be present in autocomplete as `undefined`. | ||
| @default false | ||
| */ | ||
| requireExactProps?: boolean; | ||
| }; | ||
| type DefaultExceptOptions = { | ||
| requireExactProps: false; | ||
| }; | ||
| /** | ||
| Create a type from an object type without certain keys. | ||
| We recommend setting the `requireExactProps` option to `true`. | ||
| This type is a stricter version of [`Omit`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-5.html#the-omit-helper-type). The `Omit` type does not restrict the omitted keys to be keys present on the given type, while `Except` does. The benefits of a stricter type are avoiding typos and allowing the compiler to pick up on rename refactors automatically. | ||
| This type was proposed to the TypeScript team, which declined it, saying they prefer that libraries implement stricter versions of the built-in types ([microsoft/TypeScript#30825](https://github.com/microsoft/TypeScript/issues/30825#issuecomment-523668235)). | ||
| @example | ||
| ``` | ||
| import type {Except} from 'type-fest'; | ||
| type Foo = { | ||
| a: number; | ||
| b: string; | ||
| }; | ||
| type FooWithoutA = Except<Foo, 'a'>; | ||
| //=> {b: string} | ||
| // @ts-expect-error | ||
| const fooWithoutA: FooWithoutA = {a: 1, b: '2'}; | ||
| //=> errors: 'a' does not exist in type '{ b: string; }' | ||
| type FooWithoutB = Except<Foo, 'b', {requireExactProps: true}>; | ||
| //=> {a: number} & Partial<Record<"b", never>> | ||
| // @ts-expect-error | ||
| const fooWithoutB: FooWithoutB = {a: 1, b: '2'}; | ||
| //=> errors at 'b': Type 'string' is not assignable to type 'undefined'. | ||
| // The `Omit` utility type doesn't work when omitting specific keys from objects containing index signatures. | ||
| // Consider the following example: | ||
| type UserData = { | ||
| [metadata: string]: string; | ||
| email: string; | ||
| name: string; | ||
| role: 'admin' | 'user'; | ||
| }; | ||
| // `Omit` clearly doesn't behave as expected in this case: | ||
| type PostPayload = Omit<UserData, 'email'>; | ||
| //=> { [x: string]: string; [x: number]: string; } | ||
| // In situations like this, `Except` works better. | ||
| // It simply removes the `email` key while preserving all the other keys. | ||
| type PostPayloadFixed = Except<UserData, 'email'>; | ||
| //=> { [x: string]: string; name: string; role: 'admin' | 'user'; } | ||
| ``` | ||
| @category Object | ||
| */ | ||
| type Except<ObjectType, KeysType extends keyof ObjectType, Options extends ExceptOptions = {}> = _Except<ObjectType, KeysType, ApplyDefaultOptions$1<ExceptOptions, DefaultExceptOptions, Options>>; | ||
| type _Except<ObjectType, KeysType extends keyof ObjectType, Options extends Required<ExceptOptions>> = { [KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType] } & (Options['requireExactProps'] extends true ? Partial<Record<KeysType, never>> : {}); | ||
| //#endregion | ||
| //#region ../../node_modules/.pnpm/type-fest@5.3.1/node_modules/type-fest/source/set-required.d.ts | ||
| /** | ||
| Create a type that makes the given keys required. The remaining keys are kept as is. The sister of the `SetOptional` type. | ||
| Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are required. | ||
| @example | ||
| ``` | ||
| import type {SetRequired} from 'type-fest'; | ||
| type Foo = { | ||
| a?: number; | ||
| b: string; | ||
| c?: boolean; | ||
| }; | ||
| type SomeRequired = SetRequired<Foo, 'b' | 'c'>; | ||
| // type SomeRequired = { | ||
| // a?: number; | ||
| // b: string; // Was already required and still is. | ||
| // c: boolean; // Is now required. | ||
| // } | ||
| // Set specific indices in an array to be required. | ||
| type ArrayExample = SetRequired<[number?, number?, number?], 0 | 1>; | ||
| //=> [number, number, number?] | ||
| ``` | ||
| @category Object | ||
| */ | ||
| type SetRequired<BaseType, Keys extends keyof BaseType> = (BaseType extends ((...arguments_: never) => any) ? (...arguments_: Parameters<BaseType>) => ReturnType<BaseType> : unknown) & _SetRequired<BaseType, Keys>; | ||
| type _SetRequired<BaseType, Keys extends keyof BaseType> = BaseType extends UnknownArray ? SetArrayRequired<BaseType, Keys> extends infer ResultantArray ? If<IsArrayReadonly<BaseType>, Readonly<ResultantArray>, ResultantArray> : never : Simplify< | ||
| // Pick just the keys that are optional from the base type. | ||
| Except<BaseType, Keys> & | ||
| // Pick the keys that should be required from the base type and make them required. | ||
| Required<HomomorphicPick<BaseType, Keys>>>; | ||
| /** | ||
| Remove the optional modifier from the specified keys in an array. | ||
| */ | ||
| type SetArrayRequired<TArray extends UnknownArray, Keys, Counter extends any[] = [], Accumulator extends UnknownArray = []> = TArray extends unknown // For distributing `TArray` when it's a union | ||
| ? keyof TArray & `${number}` extends never | ||
| // Exit if `TArray` is empty (e.g., []), or | ||
| // `TArray` contains no non-rest elements preceding the rest element (e.g., `[...string[]]` or `[...string[], string]`). | ||
| ? [...Accumulator, ...TArray] : TArray extends readonly [(infer First)?, ...infer Rest] ? '0' extends OptionalKeysOf<TArray> // If the first element of `TArray` is optional | ||
| ? `${Counter['length']}` extends `${Keys & (string | number)}` // If the current index needs to be required | ||
| ? SetArrayRequired<Rest, Keys, [...Counter, any], [...Accumulator, First]> | ||
| // If the current element is optional, but it doesn't need to be required, | ||
| // then we can exit early, since no further elements can now be made required. | ||
| : [...Accumulator, ...TArray] : SetArrayRequired<Rest, Keys, [...Counter, any], [...Accumulator, TArray[0]]> : never // Should never happen, since `[(infer F)?, ...infer R]` is a top-type for arrays. | ||
| : never; // Should never happen | ||
| //#endregion | ||
| //#region src/types/helper.d.ts | ||
@@ -51,0 +1026,0 @@ /** |
+2
-6
| { | ||
| "name": "form-meta", | ||
| "type": "module", | ||
| "version": "2.0.2", | ||
| "version": "2.0.3", | ||
| "description": "Type-safe form field meta resolver with flatten/purge for nested schemas", | ||
@@ -30,9 +30,5 @@ "author": "Byron <byronogis@outlook.com>", | ||
| ], | ||
| "dependencies": { | ||
| "devDependencies": { | ||
| "@standard-schema/spec": "^1.0.0", | ||
| "es-toolkit": "^1.42.0", | ||
| "type-fest": "^5.3.1", | ||
| "zod": "^4.1.13" | ||
| }, | ||
| "devDependencies": { | ||
| "typescript": "^5.9.3" | ||
@@ -39,0 +35,0 @@ }, |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
51555
186.02%0
-100%3
200%2
100%- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed