Skip to content

Suggestion: Type-check statement to verify type assignability #30809

Open
@jet2jet

Description

@jet2jet

Search Terms

type check statement compile (compilation) time

Suggestion

I wanted to check compatibilities for types from different (especially external) modules in compilation time.

import { SomeType } from 'some-external';
// ... something statement here to check if SomeType is not changed
// by update for 'some-external' or etc.

To solve it, I suggest to add type-check statement like following:

// Compile error if 'SomeType' does not satisfy the constraint 'WantedType'
//   (similar to error TS2344)
type assert SomeType extends WantedType;
// The message "Unexpected 'SomeType'" will be output if the error occurs
// - The trailing expression (message clause) must be a valid string literal
// (the message clause is not necessary for this suggestion
//  but would make easier to solve the error...)
type assert SomeType extends WantedType, "Unexpected 'SomeType'";
  • The type-check process should be same as the process for type constraints in type parameters.
  • There is already type statement, but the above statements are not conflicted because type statements requires = after BindingIdentifier (or TypeParameters).
  • Similar to [Proposal] Type assertion statement (type cast) at block-scope level #10421, but this type assert only check types; it does not cast variables.
  • extends keyword may confuse to one used in conditional type. (not ambiguous?)
    • For type assert A extends B, both A and B should accept conditional type.
  • (type assert is somewhat inspired by other languages' assert statements (especially static_assert in C/C++), but I don't know whether the words type assert are the best...)

Use Cases

  • Check compatibilities for types simply and easily
    • Useful to avoid using incompatible package versions with another packages/modules.
  • Assert types explicitly with more human-readable
    • This would not be useful for compilers/implementers, but would be useful for developers to read codes.
  • Test type definition (e.g. for unit test)

Currently we can check types statically as following:

import { SomeType } from 'some-external';
// Helper definition to check type
type TypeCheckerOfWantedType<T extends WantedType> = T;
// Error if 'SomeType' does not satisfy 'WantedType'
type CheckResultForSomeType = TypeCheckerOfWantedType<SomeType>;
// this is necessary to avoid "'CheckResultForSomeType' is declared but never used"
declare global { var _dummyVariableForCheckSomeType: CheckResultForSomeType; }

While no JavaScript codes are generated from this code, this is more complex to check.

Examples

// Must not be an error
type assert Element extends Node;
// Error in 'es5', pass in 'es2015'
type assert ObjectConstructor extends { assign: (...args: any[]) => any; },
  'Object.assign() is not available';

import { User } from 'db-library';
// Error if User does not have 'id' member with type assignable to 'number'
type assert User extends { id: number; }, 'Unexpected User type';

const a = someFunction();
if (typeof a === 'string') {
    // treat 'a' as 'string'
} else {
    // Error if narrowed type of 'a' does not have '{ data: string }'
    type assert typeof a extends { data: string; };
    // (this assert does not mean that type of 'a' is treated as '{ data: string }' here)
}

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions