Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

License

NotificationsYou must be signed in to change notification settings

woutervh-/typescript-is

Repository files navigation

typescript-isis deprecated. It still works with TS 4.8 below, but it will not be updated.

For TypeScript v4.8+, please usetypia instead.

typescript-is

TypeScript transformer that generates run-time type-checks.

npmnodeTravis (.org)npmDavidDavidNpmLicense

💿 Installation

npm install --save typescript-is# Ensure you have the required dependencies at compile time:npm install --save-dev typescript# If you want to use the decorators, ensure you have reflect-metadata in your dependencies:npm install --save reflect-metadata

💼 Use cases

If you've worked withTypeScript for a while, you know that sometimes you obtainany orunknown data that is not type-safe.You'd then have to write your own function withtype predicates that checks the foreign object, and makes sure it is the type that you need.

This library automates writing the type predicate function for you.

At compile time, it inspects the type you want to have checked, and generates a function that can check the type of a wild object at run-time.When the function is invoked, it checks in detail if the given wild object complies with your favorite type.

In particular, you may obtain wild, untyped object, in the following situations:

  • You're doing afetch call, which returns some JSON object.You don't know if the JSON object is of the shape you expect.
  • Your users are uploading a file, which is then read by your application and converted to an object.You don't know if this object is really the type you expect.
  • You're reading a JSON string fromlocalStorage that you've stored earlier.Perhaps in the meantime the string has been manipulated and is no longer giving you the object you expect.
  • Any other case where you lose compile time type information...

In these situationstypescript-is can come to your rescue.

NOTE this package aims to generate type predicates for anyserializable JavaScript object.Please checkWhat it won't do for details.

Similar projects

🎛️ Configuration

This package exposes a TypeScript transformer factory attypescript-is/lib/transformer-inline/transformer

As there currently is no way to configure the TypeScript compiler to use a transformer without using it programatically,the recommended way is to compile withttypescript.This is basically a wrapper around the TypeScript compiler that injects transformers configured in yourtsconfig.json.

(please vote here to support transformers out-of-the-box:microsoft/TypeScript#14419)

Using ttypescript

First installttypescript:

npm install --save-dev ttypescript

Then make sure yourtsconfig.json is configured to use thetypescript-is transformer:

{"compilerOptions": {"plugins": [            {"transform":"typescript-is/lib/transform-inline/transformer" }        ]    }}

Now compile usingttypescript:

npx ttsc

Using withts-node,webpack,Rollup

Please check the README ofttypescript for information on how to use it in combination withts-node,webpack, andRollup.

Note: This will not work ifts-loader is configured withtranspileOnly: true.

Using withwebpack + ts-loader withoutttypescript

If you are usingts-loader in awebpack project, you can usegetCustomTransformers as suggested in #54.This means you don't need to usettypescript or write a custom compilation script.

Example:

consttypescriptIsTransformer=require('typescript-is/lib/transform-inline/transformer').defaultmodule.exports={// I am hiding the rest of the webpack configmodule:{rules:[{test:/\.ts$/,exclude:/node_modules/,loader:'ts-loader',options:{getCustomTransformers:program=>({before:[typescriptIsTransformer(program)]})}}]}};

Note: This will not work ifts-loader is configured withtranspileOnly: true.

Options

There are some options to configure the transformer.

PropertyDescription
shortCircuitBoolean (defaultfalse). Iftrue, all type guards will returntrue, i.e. no validation takes place. Can be used for example in production deployments where doing a lot of validation can cost too much CPU.
ignoreClassesBoolean (default:false). Iftrue, when the transformer encounters a class (except forDate), it will ignore it and simply returntrue. Iffalse, an error is generated at compile time.
ignoreMethodsBoolean (default:false). Iftrue, when the transformer encounters a method, it will ignore it and simply returntrue. Iffalse, an error is generated at compile time.
ignoreFunctions(deprecated, usefunctionBehavior instead)Boolean (default:false). Iftrue, when the transformer encounters a function, it will ignore it and simply returntrue. Iffalse, an error is generated at compile time.
functionBehaviorOne oferror,ignore, orbasic (default:error). Determines the behavior of transformer when encountering a function.error will cause a compile-time error,ignore will cause the validation function to always returntrue, andbasic will do a simple function-type-check. OverridesignoreFunctions.
disallowSuperfluousObjectPropertiesBoolean (default:false). Iftrue, objects are checked for having superfluous properties and will cause the validation to fail if they do. Iffalse, no check for superfluous properties is made.
transformNonNullExpressionsBoolean (default:false). Iftrue, non-null expressions (eg.foo!.bar) are checked to not benull orundefined
emitDetailedErrorsBoolean orauto (default:auto). The generated validation functions can return detailed error messages, pointing out where and why validation failed. These messages are used byassertType<T>(), but are ignored byis<T>(). Iffalse, validation functions return empty error messages, decreasing code size.auto will generate detailed error messages for assertions, but not for type checks.true will always generate detailed error messages, matching the behaviour of version 0.18.3 and older.

If you are usingttypescript, you can include the options in yourtsconfig.json:

{"compilerOptions": {"plugins": [            {"transform":"typescript-is/lib/transform-inline/transformer","shortCircuit":true,"ignoreClasses":true,"ignoreMethods":true,"functionBehavior":"ignore","disallowSuperfluousObjectProperties":true,"transformNonNullExpressions":true,"emitDetailedErrors":"auto"            }        ]    }}

⭐ How to use

Before using, please make sure you've completedconfiguring the transformer.

In your TypeScript code, you can now import and use the type-check functionis (orcreateIs), or the type assertion functionassertType (orcreateAssertType).

Validation (is andcreateIs)

For example, you can check if something is astring ornumber and use it as such, without the compiler complaining:

import{is}from'typescript-is';constwildString:any='a string, but nobody knows at compile time, because it is cast to `any`';if(is<string>(wildString)){// returns true// wildString can be used as string!}else{// never gets to this branch}if(is<number>(wildString)){// returns false// never gets to this branch}else{// Now you know that wildString is not a number!}

You can also check your own interfaces:

import{is}from'typescript-is';interfaceMyInterface{someObject:string;without:string;}constforeignObject:any={someObject:'obtained from the wild',without:'type safety'};if(is<MyInterface>(foreignObject)){// returns trueconstsomeObject=foreignObject.someObject;// type: stringconstwithout=foreignObject.without;// type: string}

Assertions (assertType andcreateAssertType)

Or use theassertType function to directly use the object:

import{assertType}from'typescript-is';constobject:any=42;assertType<number>(object).toFixed(2);// "42.00"try{constasString=assertType<string>(object);// throws error: object is not a stringasString.toUpperCasse();// never gets here}catch(error){// ...}

Decorators (ValidateClass andAssertType)

You can also use thedecorators to automate validation in class methods.To enable this functionality, you should make sure that experimental decorators are enabled for your TypeScript project.

{"compilerOptions": {"experimentalDecorators":true    }}

You should also make sure the peer dependencyreflect-metadata is installed.

npm install --save reflect-metadata

You can then use the decorators:

import{ValidateClass,AssertType}from'typescript-is';@ValidateClass()classA{method(@AssertType()value:number){// You can safely use value as a numberreturnvalue;}}newA().method(42)===42;// truenewA().method('42'asany);// will throw error

async andPromise returning methods

AssertType can also work correctly withasync methods, returning promise rejected withTypeGuardError

To enable this functionality, you need to emit decorators metadata for your TypeScript project.

{"compilerOptions": {"emitDecoratorMetadata":true    }}

ThenAssertType will work with async methods andPromise returning methods automatically.

import{ValidateClass,AssertType}from'typescript-is';@ValidateClass()classA{asyncmethod(@AssertType({async:true})value:number){// You can safely use value as a numberreturnvalue;}methodPromise(@AssertType({async:true})value:number):Promise<number>{// You can safely use value as a numberreturnPromise.resolve(value);}}newA().method(42).then(value=>value===42/* true */);newA().method('42'asany).catch(error=>{// error will be of TypeGuardError type})newA().methodPromise('42'asany).catch(error=>{// error will be of TypeGuardError type})

If you want to throw synchronously for some reason, you can override the behaviour using with@AssertType({ async: false }):

import{ValidateClass,AssertType}from'typescript-is';@ValidateClass()classA{asyncmethod(@AssertType({async:false})value:number){// You can safely use value as a numberreturnvalue;}}newA().method(42).then(value=>value===42/* true */);newA().method('42'asany);// will throw error

If you cannot or don't want to enable decorators metadata, you still make AssertType reject with promise using@AssertType({ async: true })

import{ValidateClass,AssertType}from'typescript-is';@ValidateClass()classA{asyncmethod(@AssertType({async:true})value:number){// You can safely use value as a numberreturnvalue;}}

Strict equality (equals,createEquals,assertEquals,createAssertEquals)

This family of functions check not only whether the passed object is assignable to the specified type, but also checks that the passed object does not contain any more than is necessary. In other words: the type is also "assignable" to the object. This functionality is equivalent to specifyingdisallowSuperfluousObjectProperties in the options, the difference is that this will apply only to the specific function call. For example:

import{equals}from'typescript-is';interfaceX{x:string;}equals<X>({});// false, because `x` is missingequals<X>({x:'value'});// trueequals<X>({x:'value',y:'another value'});// false, because `y` is superfluous

To see the declarations of the functions and more examples, please check outindex.d.ts.

Formany more examples, please check out the files in thetest/ folder.There you can find all the different types that are tested for.

⛔ What it won't do

  • This library aims to be able to check any serializable data.
  • This library will not check functions. Function signatures are impossible to check at run-time.
  • This library will not check classes (except the globalDate). Instead, you are encouraged to use the nativeinstanceof operator. For example:
import{is}from'typescript-is';classMyClass{// ...}constinstance:any=newMyClass();is<MyClass>(instance);// error -> classes are not supported.// Instead, use instanceof:if(instanceinstanceofMyClass){// ...}
  • This library will not magically check unbound type parameters. Instead, make sure all type parameters are bound to a well-defined type when invoking theis function. For example:
import{is}from'typescript-is';functionmagicalTypeChecker<T>(object:any):object isT{returnis<T>(object);// error -> type `T` is not bound.}

If you stumble upon anything else that is not yet supported, please open an issue or submit a PR. 😉

🗺️ Road map

Features that are planned:

  • Promise support. Something likeassertOrReject<Type>(object) will eitherresolve(object) orreject(error).
  • Optimize the generated conditions. Things likefalse || "key" === "key" can be simplified. Might be more interesting to publish a different library that can transform a TypeScript AST, and then use it here, or use an existing one. Might be out of scope, as there are plenty of minifiers/uglifiers/manglers out there already.

🔨 Building and testing

git clone https://github.com/woutervh-/typescript-is.gitcd typescript-is/npm install# Buildingnpm run build# Testingnpm runtest

[8]ページ先頭

©2009-2025 Movatter.jp