Skip to content

Commit

Permalink
Test #469 - try assertion type
Browse files Browse the repository at this point in the history
Tried to change `typia.createAssert<T>()` function to return `asserts input is T`, but it was not possible to accomplish the requirement due to TypeScript bug.

I'll ask it to the TypeScript repo, and if it is a spec that Microsoft TypeScript team had intended, then no way to support that issue.

```typescript
const constAssert = (input: unknown): asserts input is string => {
    if (typeof input !== 'string')
        throw new Error('Assertion failed');
};

function functionAssert(input: unknown): asserts input is string {
    if (typeof input !== 'string')
        throw new Error('Assertion failed');
}

functionAssert('hello');
constAssert('hello');
```

> `Assertions require every name in the call target to be declared with an explicit type annotation.
  • Loading branch information
samchon committed Nov 12, 2023
1 parent 0631cc5 commit adb5dd8
Show file tree
Hide file tree
Showing 2,409 changed files with 37,852 additions and 34,257 deletions.
12 changes: 6 additions & 6 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export * from "./SnakeCase";
*
* @author Jeongho Nam - https://github.com/samchon
*/
export function assert<T>(input: T): T;
export function assert<T>(input: T): asserts input is T;

/**
* Asserts a value type.
Expand All @@ -72,7 +72,7 @@ export function assert<T>(input: T): T;
*
* @author Jeongho Nam - https://github.com/samchon
*/
export function assert<T>(input: unknown): T;
export function assert<T>(input: unknown): asserts input is T;

/**
* @internal
Expand Down Expand Up @@ -222,7 +222,7 @@ Object.assign(validate, Namespace.validate());
*
* @author Jeongho Nam - https://github.com/samchon
*/
export function assertEquals<T>(input: T): T;
export function assertEquals<T>(input: T): asserts input is T;

/**
* Asserts equality between a value and its type.
Expand All @@ -247,7 +247,7 @@ export function assertEquals<T>(input: T): T;
*
* @author Jeongho Nam - https://github.com/samchon
*/
export function assertEquals<T>(input: unknown): T;
export function assertEquals<T>(input: unknown): asserts input is T;

/**
* @internal
Expand Down Expand Up @@ -446,7 +446,7 @@ export function createAssert(): never;
*
* @author Jeongho Nam - https://github.com/samchon
*/
export function createAssert<T>(): (input: unknown) => T;
export function createAssert<T>(): (input: unknown) => asserts input is T;

/**
* @internal
Expand Down Expand Up @@ -533,7 +533,7 @@ export function createAssertEquals(): never;
*
* @author Jeongho Nam - https://github.com/samchon
*/
export function createAssertEquals<T>(): (input: unknown) => T;
export function createAssertEquals<T>(): (input: unknown) => asserts input is T;

/**
* @internal
Expand Down
13 changes: 10 additions & 3 deletions src/programmers/AssertProgrammer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,12 @@ export namespace AssertProgrammer {
TypeFactory.keyword("any"),
),
],
ts.factory.createTypeReferenceNode(
name ?? TypeFactory.getFullName(project.checker)(type),
ts.factory.createTypePredicateNode(
ts.factory.createToken(ts.SyntaxKind.AssertsKeyword),
ts.factory.createIdentifier("input"),
ts.factory.createTypeReferenceNode(
name ?? TypeFactory.getFullName(project.checker)(type),
),
),
undefined,
ts.factory.createBlock(
Expand Down Expand Up @@ -138,7 +142,10 @@ export namespace AssertProgrammer {
undefined,
),
ts.factory.createReturnStatement(
ts.factory.createIdentifier(`input`),
ts.factory.createAsExpression(
ts.factory.createIdentifier(`input`),
TypeFactory.keyword("any"),
),
),
],
true,
Expand Down
13 changes: 8 additions & 5 deletions src/programmers/http/HttpAssertHeadersProgrammer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,16 @@ export namespace HttpAssertHeadersProgrammer {
[ts.factory.createIdentifier("input")],
),
),
ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createIdentifier("assert"),
undefined,
[ts.factory.createIdentifier("output")],
),
),
ts.factory.createReturnStatement(
ts.factory.createAsExpression(
ts.factory.createCallExpression(
ts.factory.createIdentifier("assert"),
undefined,
[ts.factory.createIdentifier("output")],
),
ts.factory.createIdentifier("output"),
TypeFactory.keyword("any"),
),
),
Expand Down
13 changes: 8 additions & 5 deletions src/programmers/http/HttpAssertQueryProgrammer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,16 @@ export namespace HttpAssertQueryProgrammer {
[ts.factory.createIdentifier("input")],
),
),
ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createIdentifier("assert"),
undefined,
[ts.factory.createIdentifier("output")],
),
),
ts.factory.createReturnStatement(
ts.factory.createAsExpression(
ts.factory.createCallExpression(
ts.factory.createIdentifier("assert"),
undefined,
[ts.factory.createIdentifier("output")],
),
ts.factory.createIdentifier("output"),
TypeFactory.keyword("any"),
),
),
Expand Down
16 changes: 8 additions & 8 deletions src/programmers/json/JsonAssertParseProgrammer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,16 @@ export namespace JsonAssertParseProgrammer {
),
),
),
ts.factory.createReturnStatement(
ts.factory.createAsExpression(
ts.factory.createCallExpression(
ts.factory.createIdentifier("assert"),
undefined,
[ts.factory.createIdentifier("input")],
),
ts.factory.createTypeReferenceNode("any"),
ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createIdentifier("assert"),
undefined,
[ts.factory.createIdentifier("input")],
),
),
ts.factory.createReturnStatement(
ts.factory.createIdentifier("input"),
),
]),
);
};
Expand Down
14 changes: 10 additions & 4 deletions src/programmers/json/JsonAssertStringifyProgrammer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,21 @@ export namespace JsonAssertStringifyProgrammer {
},
})(modulo)(type, name),
),
ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createIdentifier("assert"),
undefined,
[ts.factory.createIdentifier("input")],
),
),
ts.factory.createReturnStatement(
ts.factory.createCallExpression(
ts.factory.createIdentifier("stringify"),
undefined,
[
ts.factory.createCallExpression(
ts.factory.createIdentifier("assert"),
undefined,
[ts.factory.createIdentifier("input")],
ts.factory.createAsExpression(
ts.factory.createIdentifier("input"),
TypeFactory.keyword("any"),
),
],
),
Expand Down
13 changes: 8 additions & 5 deletions src/programmers/protobuf/ProtobufAssertDecodeProgrammer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,16 @@ export namespace ProtobufAssertDecodeProgrammer {
[ts.factory.createIdentifier("input")],
),
),
ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createIdentifier("assert"),
undefined,
[ts.factory.createIdentifier("output")],
),
),
ts.factory.createReturnStatement(
ts.factory.createAsExpression(
ts.factory.createCallExpression(
ts.factory.createIdentifier("assert"),
undefined,
[ts.factory.createIdentifier("output")],
),
ts.factory.createIdentifier("output"),
TypeFactory.keyword("any"),
),
),
Expand Down
14 changes: 10 additions & 4 deletions src/programmers/protobuf/ProtobufAssertEncodeProgrammer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,21 @@ export namespace ProtobufAssertEncodeProgrammer {
},
})(modulo)(type, name),
),
ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createIdentifier("assert"),
undefined,
[ts.factory.createIdentifier("input")],
),
),
ts.factory.createReturnStatement(
ts.factory.createCallExpression(
ts.factory.createIdentifier("encode"),
undefined,
[
ts.factory.createCallExpression(
ts.factory.createIdentifier("assert"),
undefined,
[ts.factory.createIdentifier("input")],
ts.factory.createAsExpression(
ts.factory.createIdentifier("input"),
TypeFactory.keyword("any"),
),
],
),
Expand Down
7 changes: 5 additions & 2 deletions test/features/issues/test_issue_831_optional.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ interface IQuery {
export const test_issue_831_optional = () => {
const app: IJsonApplication =
typia.json.application<[IQuery, Partial<IQuery>, Required<IQuery>]>();
const getter = (key: string) =>
typia.assert<IJsonComponents.IObject>(app.components.schemas?.[key]);
const getter = (key: string) => {
const value = app.components.schemas?.[key];
typia.assert<IJsonComponents.IObject>(value);
return value;
};

const query: IJsonComponents.IObject = getter("IQuery");
const partial: IJsonComponents.IObject = getter("PartialIQuery");
Expand Down
4 changes: 2 additions & 2 deletions test/generated/output/assert/test_assert_ArrayAny.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ArrayAny } from "../../../structures/ArrayAny";
export const test_assert_ArrayAny = _test_assert("ArrayAny")<ArrayAny>(
ArrayAny,
)((input) =>
((input: any): ArrayAny => {
((input: any): asserts input is ArrayAny => {
const __is = (input: any): input is ArrayAny => {
const $io0 = (input: any): boolean =>
Array.isArray(input.anys) &&
Expand Down Expand Up @@ -120,6 +120,6 @@ export const test_assert_ArrayAny = _test_assert("ArrayAny")<ArrayAny>(
})
);
})(input, "$input", true);
return input;
return input as any;
})(input),
);
4 changes: 2 additions & 2 deletions test/generated/output/assert/test_assert_ArrayAtomicAlias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ArrayAtomicAlias } from "../../../structures/ArrayAtomicAlias";
export const test_assert_ArrayAtomicAlias = _test_assert(
"ArrayAtomicAlias",
)<ArrayAtomicAlias>(ArrayAtomicAlias)((input) =>
((input: any): ArrayAtomicAlias => {
((input: any): asserts input is ArrayAtomicAlias => {
const __is = (input: any): input is ArrayAtomicAlias => {
return (
Array.isArray(input) &&
Expand Down Expand Up @@ -110,6 +110,6 @@ export const test_assert_ArrayAtomicAlias = _test_assert(
})
);
})(input, "$input", true);
return input;
return input as any;
})(input),
);
4 changes: 2 additions & 2 deletions test/generated/output/assert/test_assert_ArrayAtomicSimple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ArrayAtomicSimple } from "../../../structures/ArrayAtomicSimple";
export const test_assert_ArrayAtomicSimple = _test_assert(
"ArrayAtomicSimple",
)<ArrayAtomicSimple>(ArrayAtomicSimple)((input) =>
((input: any): ArrayAtomicSimple => {
((input: any): asserts input is ArrayAtomicSimple => {
const __is = (input: any): input is ArrayAtomicSimple => {
return (
Array.isArray(input) &&
Expand Down Expand Up @@ -110,6 +110,6 @@ export const test_assert_ArrayAtomicSimple = _test_assert(
})
);
})(input, "$input", true);
return input;
return input as any;
})(input),
);
4 changes: 2 additions & 2 deletions test/generated/output/assert/test_assert_ArrayHierarchical.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ArrayHierarchical } from "../../../structures/ArrayHierarchical";
export const test_assert_ArrayHierarchical = _test_assert(
"ArrayHierarchical",
)<ArrayHierarchical>(ArrayHierarchical)((input) =>
((input: any): ArrayHierarchical => {
((input: any): asserts input is ArrayHierarchical => {
const __is = (input: any): input is ArrayHierarchical => {
const $io0 = (input: any): boolean =>
"number" === typeof input.id &&
Expand Down Expand Up @@ -325,6 +325,6 @@ export const test_assert_ArrayHierarchical = _test_assert(
})
);
})(input, "$input", true);
return input;
return input as any;
})(input),
);
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ArrayHierarchicalPointer } from "../../../structures/ArrayHierarchicalP
export const test_assert_ArrayHierarchicalPointer = _test_assert(
"ArrayHierarchicalPointer",
)<ArrayHierarchicalPointer>(ArrayHierarchicalPointer)((input) =>
((input: any): ArrayHierarchicalPointer => {
((input: any): asserts input is ArrayHierarchicalPointer => {
const __is = (input: any): input is ArrayHierarchicalPointer => {
const $io0 = (input: any): boolean =>
Array.isArray(input.value) &&
Expand Down Expand Up @@ -352,6 +352,6 @@ export const test_assert_ArrayHierarchicalPointer = _test_assert(
})
);
})(input, "$input", true);
return input;
return input as any;
})(input),
);
4 changes: 2 additions & 2 deletions test/generated/output/assert/test_assert_ArrayMatrix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ArrayMatrix } from "../../../structures/ArrayMatrix";
export const test_assert_ArrayMatrix = _test_assert("ArrayMatrix")<ArrayMatrix>(
ArrayMatrix,
)((input) =>
((input: any): ArrayMatrix => {
((input: any): asserts input is ArrayMatrix => {
const __is = (input: any): input is ArrayMatrix => {
return (
Array.isArray(input) &&
Expand Down Expand Up @@ -109,6 +109,6 @@ export const test_assert_ArrayMatrix = _test_assert("ArrayMatrix")<ArrayMatrix>(
})
);
})(input, "$input", true);
return input;
return input as any;
})(input),
);
4 changes: 2 additions & 2 deletions test/generated/output/assert/test_assert_ArrayRecursive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ArrayRecursive } from "../../../structures/ArrayRecursive";
export const test_assert_ArrayRecursive = _test_assert(
"ArrayRecursive",
)<ArrayRecursive>(ArrayRecursive)((input) =>
((input: any): ArrayRecursive => {
((input: any): asserts input is ArrayRecursive => {
const __is = (input: any): input is ArrayRecursive => {
const $io0 = (input: any): boolean =>
Array.isArray(input.children) &&
Expand Down Expand Up @@ -143,6 +143,6 @@ export const test_assert_ArrayRecursive = _test_assert(
})
);
})(input, "$input", true);
return input;
return input as any;
})(input),
);
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ArrayRecursiveUnionExplicit } from "../../../structures/ArrayRecursiveU
export const test_assert_ArrayRecursiveUnionExplicit = _test_assert(
"ArrayRecursiveUnionExplicit",
)<ArrayRecursiveUnionExplicit>(ArrayRecursiveUnionExplicit)((input) =>
((input: any): ArrayRecursiveUnionExplicit => {
((input: any): asserts input is ArrayRecursiveUnionExplicit => {
const __is = (input: any): input is ArrayRecursiveUnionExplicit => {
const $io0 = (input: any): boolean =>
"number" === typeof input.id &&
Expand Down Expand Up @@ -431,6 +431,6 @@ export const test_assert_ArrayRecursiveUnionExplicit = _test_assert(
})
);
})(input, "$input", true);
return input;
return input as any;
})(input),
);
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const test_assert_ArrayRecursiveUnionExplicitPointer = _test_assert(
"ArrayRecursiveUnionExplicitPointer",
)<ArrayRecursiveUnionExplicitPointer>(ArrayRecursiveUnionExplicitPointer)(
(input) =>
((input: any): ArrayRecursiveUnionExplicitPointer => {
((input: any): asserts input is ArrayRecursiveUnionExplicitPointer => {
const __is = (
input: any,
): input is ArrayRecursiveUnionExplicitPointer => {
Expand Down Expand Up @@ -520,6 +520,6 @@ export const test_assert_ArrayRecursiveUnionExplicitPointer = _test_assert(
})
);
})(input, "$input", true);
return input;
return input as any;
})(input),
);
Loading

0 comments on commit adb5dd8

Please sign in to comment.