- Adds missing support for BigInt literal types (#106)
- Adds missing overloads for
is()(#105) - Fixes an issue where enum names were not emitted when performing stand-in outboarding for declared enumarations (#104)
- Emits the
F_READONLYflag for object literal members when marked withreadonlykeyword and addsReflectedObjectMember#isReadonly(#103)
- When outputting type references for reified types (classes/interfaces) which were imported via
import type, an import is not generated and a structured type is outputted instead, to better match the author's intention (which would be to avoid creating a runtime dependency). (Issue #101) - Generated imports that would end in
/index.js(or ts/d.ts) are no longer simplified to the directory name in ESM mode. - Generated imports that would begin with
@types/are now simplified to a bare import for the module name (ie@types/express/foo/index.jswould becomeexpress). - The interfaces that a class is marked as implementing (ie
implements) now use the type store / referral system which should reduce duplication of generated imports
- Fix cases where references to generated imports were for the default export instead of appropriate specific exports when targeting ES modules.
- Patch release to fix the new build tooling changes
- Fixes an issue with build tools which validate that namespace imports correspond to existing exports within the module being imported (for example Angular CLI). This causes an issue when trying to consume ESM libraries which were not built with Typescript RTTI.
- No changes (Previous release on NPM had a stale build caused by changes to the NPM scripts during the recent Jest migration.)
- Fixes type references acquired via namespace imports where the type declarations file name does not correspond to the Javascript file name.
- BREAKING: Typescript 4.7 is no longer supported. Please use Typescript 4.8-5.1 instead.
matchesValue()changesmatchesValue()now accepts anoptionsobject instead of positional parameters- Adds
allowExtraPropertiesoption to matchesValue() to control whether extra options are allowed - BREAKING:
matchesValue()does not allow extra properties by default. - Fixes #92
- Expose ambient classes/interfaces as structured types
- Updated peer dependencies to acknowledge Typescript 4.7 support
- Support inspecting properties of mapped types, and uses this metadata in matchesValue()
Closes #89
- Fix duplicate items in
properties,methods,staticPropertiesandstaticMethods(and the corresponding*Namesproperties) when reflecting on a subclass which overrides methods or properties on the superclass. Retains the definition ordering. (#84)
- Adds support for array/object binding expressions in function/method parameters (ie destructuring assignment)
- Fixes an issue where
type.isPromise()returns false forPromise<T>(previously returned true only for barePromise). - Adds
isVariadic()toReflectedMethodto match the call onReflectedFunction(Pull Request) - Fixes an issue where metadata decorators were added twice for interfaces (#79)
Fixes issues where outboard decorators (ie outside of(#76)__decorate) were used when inline (normal) decorators would suffice. This makes it easier to access reflection metadata within decorators- This work is blocked by microsoft/TypeScript#49794. Until then we cannot correct the decorator load order.
- Adds support for reflecting "rest" parameters (Pull Request)
- Adds support for reflecting BigInt literals (Pull Request)
- Fixes a crash when calling matchesValue() without an initialized
errorsarray, despite the API declaration indicating this is allowed (Pull Request #70) Thanks to @CristianPi for this enhancement!
- Fixes a missed code path for enabling reflection on declared function types (as opposed to only inferred ones)
- Adds missing
as('function')overload to enable accessingReflectedFunctionRef
- Fixes an issue where the emitter outputted
RtTypeinstead ofRtParameteron the new function type refs added in 0.7.0.
- Proper support for reflecting into function types. Previously when a function type was encountered in a type position,
Functionwas emitted similar to the behavior of traditional emitDecoratorMetadata. This new reflection includes return type and parameter types, and a flags field which is reserved for future use. Use the new ReflectedFunctionRef (as('function')) to access. Note that despite the new ReflectedTypeRef kind, explicit support forisClass(Function)has been added to ensure backwards compatibility.
- Fixes an issue where RTTI assumes that the existence of a
.d.tsfile implies the existence of a corresponding.jsfile. Now RTTI will verify the existence of the.jsfile in environments which support such a check (Node.js environments). When this situation is encountered, RTTI will refuse to import the module, a type reference of typeObjectwill be emitted instead, and a warning of the following format will be emitted:RTTI: warning: Cannot import symbol 'OffendingSymbol' from declaration file 'PathToDeclaration' because there is no corresponding Javascript file alongside the declaration file! Refusing to emit type references for this symbol.
- RTTI will now remove
/index.d.ts,/index.jsor/index.tsfrom the end of an import path when generating imports to obtain references to classes, interface tokens, and enum objects. This fixes issues with referring to packages which haveindex.d.tsat the root of the package when the entrypoint for the application is something other thanindex.jsat the root of the package (for instance thewinstonpackage). See #61 for details. - The interfaces which an interface extends are now exposed via the same mechanism that we use to expose the interfaces
that a class implements. You can access these type references via
ReflectedClass#interfaceswhen theReflectedClassrepresents aninterface. See #60 for details. - Fixes an issue when referring to enums declared within function statements / expressions. See #57 for details.
- Fixes enum support to properly handle const enums.
- Adds support for reflecting properly on enums. Previously enums were emitted as unions of the numeric values of the enum. See issue #53
- Fixes an issue where the annotations for method/property/static method/static property names were not emitted if there was no methods/properties/static methods/static properties. This would cause the reflection library to fall back to property inference when it was unnecessary, causing unexpected execution of properties with getters. See issue #52
- Fixes an issue where getters would be invoked while inferring properties and methods on unannotated classes. This may
mean that some properties you might consider "methods" are listed as properties instead, but executing the getter could
have unintended side effects, and may also crash if
thisis referenced (which is common). - Fixes a bug where using
reflect()orreify()within a constructor caused the transformer to crash. See issue #54 - Adds support for
@rtti:skipto disable RTTI generation for specific parts of a codebase. This JSDoc can be applied to any node that TS supports JSDocs on (which is more than you might think). Can be very useful to work around problems or to isolate which part of your codebase is causing a crash in the transformer. We use this internally to allow typescript-rtti's test suite to be roundtripped within the "corpus" test suite.
- Fixes a bug when referring to interfaces that do not have tokens (because they were not compiled with the transformer)
This bug exhibits as:
Cannot read properties of undefined (reading 'RΦ'). See #48
- Adds support for object literal type references
- Fixes issues where synthetic imports are hoisted to the top of the file,
which particularly can cause problems when
reflect-metadataor other "must import first" imports are present in the file
- Adds
ReflectedTypeRef#equals()(and the supporting protectedReflectedTypeRef#matches()family of functions) for comparing type references for equivalence.
- Fixes some failures where array types are used with
noLibenabled - Ensures that
Objectwill be emitted when encountering types with missing symbols - Provide better DX for cases where
noLibcauses problems - Fixes numerous issues with
design:*metadata and how RTTI handles importing classes for those - RTTI's global detection is now much more reliable, preventing issues where RTTI tries to
import a symbol from a declaration-only location when it is not required (for instance
Bufferin Node.js).
- Fix for bug when accessing a type reference for a default-exported interface
- Fixes for intrinsic type checks (isNull(), isUndefined(), isTrue(), isFalse())
- Tighten type assertions in the reflection API to reduce easy mistakes
- Fix for the new
@rtti:callsite 1JSDoc optin
- Fix for using
require()for Node-specific imports breaks webpack builds though they are properly guarded (so that the transformer can work properly in the browser)
- Add support for
@rtti:callsiteJSDoc tag as a way to opt in to receiving call-site reflection data without directly referencingtypescript-rttitypes (useful for third parties to opt in and introspect on typescript-rtti's metadata). This will be important for the new@typescript-rtti/reflectlibrary. - Overhauls handling of classes/interfaces defined external to the file being processed. This fixes a number of cases
which were previously broken, such as those noted by #27 and #28. The transformer is now aware of
node_modulesin a much better way which can analyzepackage.jsonto simplify imports in cases where the best import found is the entrypoint of the library you are using (for instance import fromgraphqlinstead ofgraphql/index). These changes are important to ensure that typescript-rtti does not cause dependencies on private details (ie filesystem layout) of packages, as those may change version-to-version without a semver major bump. - Fixes issues where typescript-rtti tries to import interface tokens (
IΦ*) from the Typescript standard library in the vain hope that they exist.
- Do not emit for
declare class - Fixes issues where legacy metadata (
design:*) was output without generating a suitable import, leading toTypeErrorat runtime
- Fix for compile-time crash when mapped type has no
aliasTypeArguments - Fix for properties which use a string literal name
- Add missing support for class expressions
- Add missing support for private identifiers (
#foo)
- Support for metadata on properties with computed names (including symbols)
- Added
reflect-metadataas a peer dependency. It has always been required for the correct operation of the transformer, but the peer dependency was missing until this version.
- Additional checks for bad
design:paramtypesemit
- Guard at runtime for bad
design:paramtypesemit and ensureparametersalways returns an array even if no metadata sources are available.
- Support for reflecting on primitive values (number, boolean, string, etc)
- Fixes a bug where initializers did not work correctly
- Fixes a bug where constructor parameters did not emit type information when inferred (instead of defined explicitly)
- Fixes a bug where ReflectedMethod.for(function) failed to resolve the
rt:htype resolver, producing incorrect results.
- Reflected parameters now have an
indexproperty for convenience. - Reflected parameters now have appropriate
parentproperties - Reflected parameters involving a class (constructor/method parameters) now have
classproperties.
- Fixes issues where external interfaces were imported using absolute file paths which produced builds that could not be moved
- Fixes issues where classes/interfaces defined within functions would not be properly accessible via reflection due to the per-file type store changes.
- Allow
ReflectedTypeRef#isInterface()without passing an interface token - Added
metadata()convenience function toReflectedClass,ReflectedMemberandReflectedFunction. This method allows you to get or create a metadata key on the reflected target. - Modified
defineMetadata()onReflectedMember,ReflectedFunctionto return the value of the new metadata item for consistency with the corresponding method onReflectedClass. Previously these methods returned nothing.
- Fixes an issue where matchesValue() behavior for union/intersection was swapped
- Fixes an issue where the isOptional flag was not emitted properly for properties/methods
- Fixes an issue where interfaces did not wrap metadata declarations in ExpressionStatement leading to automatic semicolon insertion (ASI) bugs. This was previously fixed but only for classes.
- Fixes a bug where reflect(ClassConstructor) becomes confused due to injected callSite object
- Fixes a bug where nested calls were not checked for call-site reflection.
- Breaking:
reflect<T>()now returnsReflectedTypeRef. This enables the genericTparameter to be any reflectable type, for instancereflect<string | number>()orreflect<123>().
- Added call-site reflection: Reflect on the type information at the location where your function is called
- Fixes an issue where
RtAnyRef#kindreportedunknowninstead ofany - Add ability to detect whether a return type is inferred or explicit (#16)
- Fixes an issue where the value of
emitDecoratorMetadatawas lost and reset tofalsewhen run withints-jest - Properly emits for inferred async return types
- Fix: the name of function expressions assigned to property and variable declarations are now retained when they are annotated.
- Fixed handling of inferred generic types
- Added missing handling for property get/set accessors
- String-like and number-like return types (enums mainly) now emit the appropriate type for
design:returntype - Fixed an issue where
thisparameters were included in parameter lists unintentionally, including indesign:paramtypes - Revised emit to create a
__RΦobject containing the metadata and function annotation helpers instead of__RtΦand__RfΦrespectively - Enabled emitting of recursive types
This was done by revising emit to use the
__RΦobject as a central store of type information for the current file, with the element-level metadata accessing this metadata as needed. NOTE: This change is backwards compatible- As a side effect of this change, the total byte size of emitted metadata should be heavily reduced, with files containing many identical type references seeing the largest benefits.
- Fixes an additional case where
nullwas used instead ofundefinedwhen generating typescript AST elements
- Fixes an issue where
nullwas used instead ofundefinedon the forward reference arrow functions. This could cause problems when using typescript-rtti in concert with other transformers (for instance, when usingts-jest)
- Minimum Typescript version is now 4.5.5
- Minimum Node.js version is now v14
- The test suite now builds
razmin,@astronautlabs/bitstream, andtypescript-rtti(itself) using its own transformer and the test suites of those libraries successfully pass (corpus testing). Additional libraries are on the roadmap for being included in the test corpus including@alterior-mvc/alteriorand@astronautlabs/jwt. Accepting PRs for additional libraries to include in the test suite. - Found and fixed as part of corpus testing:
- Removed emitting of
design:*metadata where Typescript does not emit it to better match semantics and fix compilation issues - forward references in interface methods caused build failures with emitDecoratorMetadata compatibility
- numerous corner case build issues discovered through corpus testing
- metadata was not emitted for elements within function expressions and arrow functions
- emitDecoratorMetadata compatibility producing different results from the standard implementation
- metadata definition statements were emitted as expressions (ie without semicolons) leading to incorrect JS output
- Removed emitting of
- Transformer is now considered stable for build with any codebase. Please file an issue if you receive a compilation failure.
- Arrow functions and function expressions are now supported
- Reflected flags are now used to determine what kind of value is being passed to
reflect(value). This enables differentiating between functions and classes according to their flags. For functions without RTTI, reflect() returnsReflectedClass(instead ofReflectedFunction) because there is no way to determine at runtime (without RTTI) whether afunctionexpression is a plain function or a constructor. UseReflectedFunction.for(value)instead if you know the value is intended to be a regular function, as opposed to a constructor. Note that arrow functions do not have this issue as they are not constructable, and thus they have no prototype. reflect(value)now has better typed overrides to clarify what kind of value you will get back depending on what value you pass in- You can now obtain
ReflectedMethoddirectly from a method function, even without knowing what class it belongs to. For instance:class A { foo() { } } expect(reflect(A.foo)).to.be.instanceOf(ReflectedMethod) expect(reflect(A.foo).class).to.equal(reflect(A))
- Fixes a failure when no return type inference is available on a function declaration
- [Breaking]
ReflectedFunction#rawParameterMetadataandReflectedProperty#rawParameterMetadataare now marked@internal.RawParameterMetadatais no longer exported. UseparameterNamesandparameterTypesinstead and avoid relying on the underlying RTTI metadata. - [Breaking]
isPrivate,isPublicandisProtectedaccessors onReflectedClassare removed. These were always false. - Adds support for emitting static method/property lists (rt:SP and rt:Sm)
- Improved documentation
- [Breaking] The public flag (
F_PUBLIC,$) is no longer emitted if the method or property is not explicitly marked public. ReflectedMember#isPublicnow returns true if no visibility flags are present (ie default visibility).- Added
ReflectedMember#isMarkedPublicto check if a member is specifically marked public. - Added support for parameter initializers (ie default values). Note that care should be taken when evaluating
initializers
because they may depend on
this.evaluateInitializer(thisObject)is provided to make this simpler.
- Support more inferred types (class/interface/union/intersection)
- Support function return type / parameter types
- Support reflecting on abstract methods
- Support the abstract flag on methods
- Support async flag on methods and functions
- Emit the interface flag on interfaces
- Added support for
voidtype - Breaking: You must now use ReflectedClass.for(MyClass) instead of new ReflectedClass(MyClass)
- Instances of ReflectedClass are now cached and shared. As a result all instances of ReflectedClass are now sealed
- Breaking:
ReflectedMethod#parameterTypesnow has typeReflectedTypeRef[]which allows them to express the full range of types possible. Previously the raw type refs (for instance type resolvers such as() => String) was returned here which inappropriately exposed the underlying metadata format. - Added support for is() type predicates and as() casting to
ReflectedTypeReffor ease of use - Added several more variants of
ReflectedTypeRefto match how the capabilities of the library have evolved ReflectedMethod#parameterTypescan now source metadata fromdesign:paramtypes- Support for interfaces, use
reify<MyInterface>()to obtain interface tokens - Added
reflect<MyInterface>(),reflect(MyClass),reflect(myInstance)shortcuts for obtainingReflectedClassinstances
- Added better handling for literal types to
ReflectedClass.- You can now expect
isClass(Boolean)to be true for typestrueandfalse,isClass(Object)to be true fornull,isClass(Number)to be true for numeric literals andisClass(String)to be true for string literals. - Added
isLiteral(value)to check for a literal value
- You can now expect
- Fixed a bug where all unknown types were reported as
Boolean - Added support for
undefinedtype - Added a number of helpers for checking for literal types to
ReflectedTypeRef
- Added support for type literal types, ie
foo(bar : false, baz : null, foobar : 123)
- Fix: do not crash when property has no type (https://github.com/rezonant/typescript-rtti/commit/474eddf15160457e57a786f0c67918e99a11d8c2)
Features
- Added support for serializing generic types including their type arguments. This means you can now obtain the type of
a
Promisefor instance (provided that the referenced type has a value at runtime). Additionally, cases where the type references an interface, and that interface has type parameters will now emit a generic type which exposes the types of the parameters, even if the interface itself does not have a runtime value. For instanceInterfaceA<InterfaceB>would emit a generic type with base typeObjectand one parameter type ofObject.
Breaking
- Made the structure of the
RtTypeReffamily of interfaces internal along with creation ofReflectedTypeRefand itsrefproperty. Technically this is a breaking change, but these interfaces have only been exposed since v0.0.14
Breaking
- changes emission of union, intersection
- sample input:
string | number - before:
{ kind: 'union', types: [String, Number] } - after:
{ TΦ: T_UNION, t: [String, Number] }
- sample input:
- changes array emission to match.
- sample input:
string[] - before:
[ String ] - after:
{ TΦ: T_ARRAY, e: String }
- sample input:
- changes API (ie
ReflectedClass) to properly expose type references (such as union, intersection, arrays, tuples, etc), not just function references
Features
- support for tuple types,
[ str : string, num : number ]emits{ TΦ: T_TUPLE, e: [ { n: 'str', t: String }, { n: 'num', t: Number } ] }
Features
- support union and intersection types. In place of a Function type you get
{ kind: 'union', types: [...] }or{ kind: 'intersection', types: [...] }. - support reading design:* metadata via ReflectedClass, ReflectedProperty, ReflectedMethod
- support for static methods/properties
Fixes
- emitDecoratorMetadata reverts to false on multi-file projects causing most
design:*metadata not to be emitted - prepending require() on a property access expression did not work in all cases
- crash when an unsupported type reference is encountered (emit
Objectinstead and print a warning) - runtime crash when an interface is returned (emit
Objectinstead of a reference to a non-runtime identifier) - runtime crash when a type paramter is returned (emit
Objectinstead of a reference to a non-runtime identifier) - now uses TypeReferenceSerializationKind to determine if a type has a value. Unfortunately this is a TS internal feature which means it may change out from under us on future TS versions
Features
- support
any(emitObject) - support
Function(emitFunction) - improve failure handling: print the file which caused an error to help the project author tell us what we need to fix
Tests
- tests now include TS libraries for ensuring we handle builtin types correctly
- using the
trace: trueoption ofrunSimplenow outputs typescript diagnostics for better debugging - more tests for primitive types and
unknown