Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add pick and omit methods to InterfaceType #101

Merged
merged 1 commit into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions etc/types.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export interface Failure {
// @public
export type FailureDetails = ValidationDetails & MessageDetails;

// @public (undocumented)
// @public
export type FullType<Props extends Properties> = TypeImpl<InterfaceType<Simplify<Props>, Simplify<TypeOfProperties<Writable<Props>>>>>;

// @public (undocumented)
Expand All @@ -148,19 +148,28 @@ export interface InterfaceMergeOptions {
}

// @public
export class InterfaceType<Props extends Properties, ResultType> extends BaseObjectLikeTypeImpl<ResultType> implements TypedPropertyInformation<Props> {
export interface InterfacePickOptions {
applyParser?: boolean;
name?: string | null;
omitValidations?: true;
}

// @public
export class InterfaceType<Props extends Properties, ResultType extends unknownRecord> extends BaseObjectLikeTypeImpl<ResultType> implements TypedPropertyInformation<Props> {
constructor(
propsInfo: PropertiesInfo<Props>, options: InterfaceTypeOptions);
accept<R>(visitor: Visitor<R>): R;
readonly basicType: 'object';
// (undocumented)
readonly isDefaultName: boolean;
readonly keys: readonly (keyof Props)[];
readonly keys: readonly (keyof Props & keyof ResultType & string)[];
maybeStringify(value: ResultType): string;
mergeWith<OtherProps extends Properties, OtherType>(...args: [type: InterfaceType<OtherProps, OtherType>] | [name: string, type: InterfaceType<OtherProps, OtherType>] | [options: InterfaceMergeOptions, type: InterfaceType<OtherProps, OtherType>]): MergeType<Props, ResultType, OtherProps, OtherType>;
mergeWith<OtherProps extends Properties, OtherType extends unknownRecord>(...args: [type: InterfaceType<OtherProps, OtherType>] | [name: string, type: InterfaceType<OtherProps, OtherType>] | [options: InterfaceMergeOptions, type: InterfaceType<OtherProps, OtherType>]): MergeType<Props, ResultType, OtherProps, OtherType>;
readonly name: string;
omit<const Key extends keyof Props & keyof ResultType & string>(...args: [keys: OneOrMore<Key>] | [name: string, keys: OneOrMore<Key>] | [options: InterfacePickOptions, keys: OneOrMore<Key>]): PickType<Props, ResultType, Exclude<keyof Props & keyof ResultType & string, Key>>;
// (undocumented)
readonly options: InterfaceTypeOptions;
pick<const Key extends keyof Props & keyof ResultType & string>(...args: [keys: OneOrMore<Key>] | [name: string, keys: OneOrMore<Key>] | [options: InterfacePickOptions, keys: OneOrMore<Key>]): PickType<Props, ResultType, Key>;
// (undocumented)
readonly possibleDiscriminators: readonly PossibleDiscriminator[];
// (undocumented)
Expand All @@ -183,6 +192,7 @@ export interface InterfaceTypeOptions {

// @public (undocumented)
export interface InterfaceTypeOptionsWithPartial extends InterfaceTypeOptions {
// @deprecated
partial?: boolean;
}

Expand Down Expand Up @@ -274,7 +284,7 @@ export type LiteralValue = string | number | boolean | null | undefined | void;
// @public
export type MergeIntersection<T> = T extends Record<PropertyKey, unknown> ? Simplify<T> : T;

// @public (undocumented)
// @public
export type MergeType<Props extends Properties, ResultType, OtherProps extends Properties, OtherResultType> = TypeImpl<InterfaceType<Simplify<Omit<Props, keyof OtherProps> & OtherProps>, Simplify<Omit<ResultType, keyof OtherResultType> & OtherResultType>>>;

// @public
Expand Down Expand Up @@ -365,12 +375,15 @@ export interface ParserOptions {
// @public
export function partial<Props extends Properties>(...args: [props: Props] | [name: string, props: Props] | [options: InterfaceTypeOptions, props: Props]): PartialType<Props>;

// @public (undocumented)
// @public
export type PartialType<Props extends Properties> = TypeImpl<InterfaceType<Simplify<Props>, Simplify<Partial<TypeOfProperties<Writable<Props>>>>>>;

// @public (undocumented)
export function pattern<const BrandName extends string>(name: BrandName, regExp: RegExp, customMessage?: StringTypeConfig['customMessage']): Type<Branded<string, BrandName>, StringTypeConfig>;

// @public
export type PickType<Props extends Properties, ResultType, Key extends keyof Props & keyof ResultType & string> = TypeImpl<InterfaceType<Simplify<Pick<Props, Key>>, Simplify<Pick<ResultType, Key>>>>;

// @public
export type PossibleDiscriminator = {
readonly path: readonly string[];
Expand Down
2 changes: 2 additions & 0 deletions markdown/types.fulltype.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

## FullType type

Result of the [object()](./types.object.md) function.

**Signature:**

```typescript
Expand Down
2 changes: 2 additions & 0 deletions markdown/types.interfacemergeoptions.omitparsers.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ omitParsers?: true;
Parsers are not reused when merging multiple interface types using [withOptional](./types.interfacetype.withoptional.md)<!-- -->, [withRequired](./types.interfacetype.withrequired.md) and [mergeWith](./types.interfacetype.mergewith.md)<!-- -->. When a custom parser is encountered by Skunk Team types, an Error will be thrown. Use this option to ignore the parsers and continue with the merge.

This is to ensure that custom parser are never accidentally lost by adding additional properties to an existing type.

Alternatively, it is always possible to use an [intersection()](./types.intersection.md) instead.
2 changes: 2 additions & 0 deletions markdown/types.interfacemergeoptions.omitvalidations.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ By default, custom validations (i.e. validations that are added to a type using
Note that reuse of custom validations only works when no properties overlap between the types that are being merged. As long as the properties don't overlap we can be sure that the merged type is assignable to each of the original types (`A & B` is assignable to both `A` and `B`<!-- -->). Therefore, the validations are still safe to run, even though the type has been extended with additional properties.

When overlap is detected in the property-names of the types and any custom validation is encountered by Skunk Team types, an Error will be thrown. Use this option to ignore the custom validations and continue with the merge.

Alternatively, it is always possible to use an [intersection()](./types.intersection.md) instead.
21 changes: 21 additions & 0 deletions markdown/types.interfacepickoptions.applyparser.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@skunkteam/types](./types.md) &gt; [InterfacePickOptions](./types.interfacepickoptions.md) &gt; [applyParser](./types.interfacepickoptions.applyparser.md)

## InterfacePickOptions.applyParser property

Choose whether to apply the custom parser from the base type onto the newly "picked type" or not.

**Signature:**

```typescript
applyParser?: boolean;
```

## Remarks

By default, custom parsers (i.e. parsers that are added to a type using [BaseTypeImpl.withParser()](./types.basetypeimpl.withparser.md) or [BaseTypeImpl.autoCast](./types.basetypeimpl.autocast.md)<!-- -->) are not reused when a new type is created using [InterfaceType.pick()](./types.interfacetype.pick.md) and [InterfaceType.omit()](./types.interfacetype.omit.md)<!-- -->.

However, it is possible to reuse a parser that is set on the base type. Parsers have a single input of type `unknown` and may produce anything (also with type `unknown`<!-- -->). The result of a parser will always be validated afterwards by the type it is applied to. Technically, any parser is applicable to any type, but it might not make sense to do so. Therefore, you can choose to apply it or not with this option.

If a custom parser is found on the base type, then this options is mandatory.
21 changes: 21 additions & 0 deletions markdown/types.interfacepickoptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@skunkteam/types](./types.md) &gt; [InterfacePickOptions](./types.interfacepickoptions.md)

## InterfacePickOptions interface

Options for [InterfaceType.pick()](./types.interfacetype.pick.md) and [InterfaceType.omit()](./types.interfacetype.omit.md)<!-- -->.

**Signature:**

```typescript
interface InterfacePickOptions
```

## Properties

| Property | Modifiers | Type | Description |
| ------------------------------------------------------------------- | --------- | -------------- | ---------------------------------------------------------------------------------------------------------------- |
| [applyParser?](./types.interfacepickoptions.applyparser.md) | | boolean | _(Optional)_ Choose whether to apply the custom parser from the base type onto the newly "picked type" or not. |
| [name?](./types.interfacepickoptions.name.md) | | string \| null | _(Optional)_ The optional name for the new type, or <code>null</code> to force a generated TypeScript-like name. |
| [omitValidations?](./types.interfacepickoptions.omitvalidations.md) | | true | _(Optional)_ Suppress the error about existing custom validations on the base type. |
19 changes: 19 additions & 0 deletions markdown/types.interfacepickoptions.name.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@skunkteam/types](./types.md) &gt; [InterfacePickOptions](./types.interfacepickoptions.md) &gt; [name](./types.interfacepickoptions.name.md)

## InterfacePickOptions.name property

The optional name for the new type, or `null` to force a generated TypeScript-like name.

**Signature:**

```typescript
name?: string | null;
```

## Remarks

When omitted, it will follow the name of original type (on the left). It will either use the custom name of that type or generate a new default TypeScript-like name if the type did not have a custom name.

Use this `name` setting with a `string` to provide a new custom name or use `null` to force a generated TypeScript-like name, even if the original type has a custom name.
21 changes: 21 additions & 0 deletions markdown/types.interfacepickoptions.omitvalidations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@skunkteam/types](./types.md) &gt; [InterfacePickOptions](./types.interfacepickoptions.md) &gt; [omitValidations](./types.interfacepickoptions.omitvalidations.md)

## InterfacePickOptions.omitValidations property

Suppress the error about existing custom validations on the base type.

**Signature:**

```typescript
omitValidations?: true;
```

## Remarks

Validations are not reused when picking or omitting properties from a base type. This is because validations work on the original base type. The new type, with some properties omitted, is not assignable to the original type. Therefore, we cannot reliably call the validations with instances of the new type.

When a custom validation is encountered by Skunk Team types, an Error will be thrown. Use this option to ignore the validations and continue with the pick or omit operation.

This is to ensure that custom validations are never accidentally lost.
2 changes: 1 addition & 1 deletion markdown/types.interfacetype.keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ The keys (property-names) for this object-like type.
**Signature:**

```typescript
readonly keys: readonly (keyof Props)[];
readonly keys: readonly (keyof Props & keyof ResultType & string)[];
```
6 changes: 4 additions & 2 deletions markdown/types.interfacetype.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The implementation behind types created with [object()](./types.object.md) and [
**Signature:**

```typescript
declare class InterfaceType<Props extends Properties, ResultType> extends BaseObjectLikeTypeImpl<ResultType> implements TypedPropertyInformation<Props>
declare class InterfaceType<Props extends Properties, ResultType extends unknownRecord> extends BaseObjectLikeTypeImpl<ResultType> implements TypedPropertyInformation<Props>
```

**Extends:** [BaseObjectLikeTypeImpl](./types.baseobjectliketypeimpl.md)<!-- -->&lt;ResultType&gt;
Expand All @@ -28,7 +28,7 @@ declare class InterfaceType<Props extends Properties, ResultType> extends BaseOb
| ------------------------------------------------------------------------- | --------------------- | ------------------------------------------------------------------------------ | --------------------------------------------------------------------------- |
| [basicType](./types.interfacetype.basictype.md) | <code>readonly</code> | 'object' | The kind of values this type validates. |
| [isDefaultName](./types.interfacetype.isdefaultname.md) | <code>readonly</code> | boolean | |
| [keys](./types.interfacetype.keys.md) | <code>readonly</code> | readonly (keyof Props)\[\] | The keys (property-names) for this object-like type. |
| [keys](./types.interfacetype.keys.md) | <code>readonly</code> | readonly (keyof Props &amp; keyof ResultType &amp; string)\[\] | The keys (property-names) for this object-like type. |
| [name](./types.interfacetype.name.md) | <code>readonly</code> | string | The name of the Type. |
| [options](./types.interfacetype.options.md) | <code>readonly</code> | [InterfaceTypeOptions](./types.interfacetypeoptions.md) | |
| [possibleDiscriminators](./types.interfacetype.possiblediscriminators.md) | <code>readonly</code> | readonly [PossibleDiscriminator](./types.possiblediscriminator.md)<!-- -->\[\] | |
Expand All @@ -43,6 +43,8 @@ declare class InterfaceType<Props extends Properties, ResultType> extends BaseOb
| [accept(visitor)](./types.interfacetype.accept.md) | | Accept a visitor (visitor pattern). |
| [maybeStringify(value)](./types.interfacetype.maybestringify.md) | | Create a JSON string of the given value, using the type information of the current type. Matches the specs of <code>JSON.stringify</code>. |
| [mergeWith(args)](./types.interfacetype.mergewith.md) | | Create a new type by merging all properties of the given type into the properties of this type. |
| [omit(args)](./types.interfacetype.omit.md) | | Create a new type that consists of all properties of the base type, except those mentioned, similar to the builtin <code>Omit</code> type. |
| [pick(args)](./types.interfacetype.pick.md) | | Create a new type that consists only of the mentioned properties similar to the builtin <code>Pick</code> type. |
| [toPartial(name)](./types.interfacetype.topartial.md) | | Clone this type with all properties marked optional. |
| [typeValidator(input, options)](./types.interfacetype.typevalidator.md) | <code>protected</code> | The actual validation-logic. |
| [withOptional(args)](./types.interfacetype.withoptional.md) | | Create a type with all properties of the current type, plus the given optional properties. |
Expand Down
2 changes: 1 addition & 1 deletion markdown/types.interfacetype.mergewith.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Create a new type by merging all properties of the given type into the propertie
**Signature:**

```typescript
mergeWith<OtherProps extends Properties, OtherType>(...args: [type: InterfaceType<OtherProps, OtherType>] | [name: string, type: InterfaceType<OtherProps, OtherType>] | [options: InterfaceMergeOptions, type: InterfaceType<OtherProps, OtherType>]): MergeType<Props, ResultType, OtherProps, OtherType>;
mergeWith<OtherProps extends Properties, OtherType extends unknownRecord>(...args: [type: InterfaceType<OtherProps, OtherType>] | [name: string, type: InterfaceType<OtherProps, OtherType>] | [options: InterfaceMergeOptions, type: InterfaceType<OtherProps, OtherType>]): MergeType<Props, ResultType, OtherProps, OtherType>;
```

## Parameters
Expand Down
23 changes: 23 additions & 0 deletions markdown/types.interfacetype.omit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@skunkteam/types](./types.md) &gt; [InterfaceType](./types.interfacetype.md) &gt; [omit](./types.interfacetype.omit.md)

## InterfaceType.omit() method

Create a new type that consists of all properties of the base type, except those mentioned, similar to the builtin `Omit` type.

**Signature:**

```typescript
omit<const Key extends keyof Props & keyof ResultType & string>(...args: [keys: OneOrMore<Key>] | [name: string, keys: OneOrMore<Key>] | [options: InterfacePickOptions, keys: OneOrMore<Key>]): PickType<Props, ResultType, Exclude<keyof Props & keyof ResultType & string, Key>>;
```

## Parameters

| Parameter | Type | Description |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- |
| args | \[keys: [OneOrMore](./types.oneormore.md)<!-- -->&lt;Key&gt;\] \| \[name: string, keys: [OneOrMore](./types.oneormore.md)<!-- -->&lt;Key&gt;\] \| \[options: [InterfacePickOptions](./types.interfacepickoptions.md)<!-- -->, keys: [OneOrMore](./types.oneormore.md)<!-- -->&lt;Key&gt;\] | |

**Returns:**

[PickType](./types.picktype.md)<!-- -->&lt;Props, ResultType, Exclude&lt;keyof Props &amp; keyof ResultType &amp; string, Key&gt;&gt;
23 changes: 23 additions & 0 deletions markdown/types.interfacetype.pick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@skunkteam/types](./types.md) &gt; [InterfaceType](./types.interfacetype.md) &gt; [pick](./types.interfacetype.pick.md)

## InterfaceType.pick() method

Create a new type that consists only of the mentioned properties similar to the builtin `Pick` type.

**Signature:**

```typescript
pick<const Key extends keyof Props & keyof ResultType & string>(...args: [keys: OneOrMore<Key>] | [name: string, keys: OneOrMore<Key>] | [options: InterfacePickOptions, keys: OneOrMore<Key>]): PickType<Props, ResultType, Key>;
```

## Parameters

| Parameter | Type | Description |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- |
| args | \[keys: [OneOrMore](./types.oneormore.md)<!-- -->&lt;Key&gt;\] \| \[name: string, keys: [OneOrMore](./types.oneormore.md)<!-- -->&lt;Key&gt;\] \| \[options: [InterfacePickOptions](./types.interfacepickoptions.md)<!-- -->, keys: [OneOrMore](./types.oneormore.md)<!-- -->&lt;Key&gt;\] | |

**Returns:**

[PickType](./types.picktype.md)<!-- -->&lt;Props, ResultType, Key&gt;
Loading