-
-
Notifications
You must be signed in to change notification settings - Fork 7.3k
fix(typescript): typecheck generated samples + fixes #19903
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
Changes from all commits
5613a5a
6b0e581
5d52f69
a120097
440eb12
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| name: TypeScript clients type checks | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths: | ||
| - samples/** | ||
joscha marked this conversation as resolved.
Show resolved
Hide resolved
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @joscha can we run this only if there's a change in the typescript-related samples? #20000 (a recent PR) shows the workflow failed: https://github.com/OpenAPITools/openapi-generator/actions/runs/11606840555/job/32319917402?pr=20000 can you please take a look?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can reduce it a bit more. In order to be super precise we'd need the full dependency graph, that is tricky as it includes any package.lock, node versions, etc. - it's not impossible but the repository is not set up for it currently, we'd want to also get the node dependency from nix for example. I can probably improve it a bit more, however I won't have access to a computer for a few more days. If the tests fail regularly with false positives, feel free to comment out the yaml and I'll fix and reenable when I get access to a computer. |
||
| - bin/ts-typecheck-all.sh | ||
| - .github/workflows/samples-typescript-typecheck.yaml | ||
| jobs: | ||
| build: | ||
| name: Typecheck TypeScript samples | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we were to generate this file, we could used the |
||
| node-version: | ||
| - 20 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: ${{ matrix.node-version }} | ||
|
|
||
| - name: Run type checker | ||
| run: ./bin/ts-typecheck-all.sh | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| log() { | ||
| echo "$@" >&2 | ||
| } | ||
|
|
||
| npm_install() { | ||
| # --ignore-scripts because we don't want to run any pre- or postinstall scripts | ||
| # --no-package-lock because we don't want to update or create the package-lock.json | ||
| # --no-fund because we don't want to check for funding | ||
| # --no-audit because we don't want to run an audit | ||
| # --suppress-warnings because we don't want to see any warnings whilst type checking | ||
| npm i \ | ||
| --suppress-warnings \ | ||
| --ignore-scripts \ | ||
| --no-package-lock \ | ||
| --no-fund \ | ||
| --no-audit \ | ||
| "$@" | ||
| } | ||
|
|
||
| main() { | ||
| local root_dir | ||
| root_dir=$(git rev-parse --show-toplevel) | ||
| local dir | ||
|
|
||
| for dir in $(git ls-files samples | grep 'tsconfig.json$' | xargs -n1 dirname | sort -u); do | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We find all checked in samples that have a |
||
| if [[ ! -f "${root_dir}/${dir}/.openapi-generator-ignore" ]]; then | ||
| # This is not a generated sample; skip it | ||
| continue | ||
| fi | ||
| if [[ ! -f "${root_dir}/${dir}/package.json" ]]; then | ||
| # we can't really guarantee that all dependencies are there to do a typecheck... | ||
| continue | ||
| fi | ||
| log "➤ ${dir}" | ||
| pushd "${root_dir}/${dir}" > /dev/null | ||
| npm_install \ | ||
| || npm_install --force # --force because we have some incompatible peer-dependencies that can't be fixed | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can see in the CI logs, but basically there are a couple really really outdated dependencies, which can't even be updated anymore, like https://github.com/angular/tsickle/ for example. Hence we need to sometimes override incompatible peer dependencies, etc. |
||
| npm exec [email protected] --yes -- tsc --noEmit | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this does the actual type checking and fails the job if there are errors |
||
| log "✓ ${dir}" | ||
| log | ||
| popd > /dev/null | ||
| done | ||
| } | ||
|
|
||
| main "$@" | ||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -338,6 +338,7 @@ public AbstractTypeScriptClientCodegen() { | |||||||||
| typeMapping.put("Array", "Array"); | ||||||||||
| typeMapping.put("array", "Array"); | ||||||||||
| typeMapping.put("boolean", "boolean"); | ||||||||||
| typeMapping.put("decimal", "string"); | ||||||||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. without this change, openapi-generator/modules/openapi-generator/src/test/resources/3_0/snakecase-discriminator.yaml Lines 1556 to 1558 in 6b0e581
for example would exopect a full-blown Line 16 in ce09134
|
||||||||||
| typeMapping.put("string", "string"); | ||||||||||
| typeMapping.put("int", "number"); | ||||||||||
| typeMapping.put("float", "number"); | ||||||||||
|
|
@@ -746,6 +747,11 @@ public String toDefaultValue(Schema p) { | |||||||||
| return p.getDefault().toString(); | ||||||||||
| } | ||||||||||
| return UNDEFINED_VALUE; | ||||||||||
| } else if (ModelUtils.isDecimalSchema(p)) { | ||||||||||
| if (p.getDefault() != null) { | ||||||||||
| return p.getDefault().toString(); | ||||||||||
| } | ||||||||||
| return UNDEFINED_VALUE; | ||||||||||
| } else if (ModelUtils.isDateSchema(p)) { | ||||||||||
| if (p.getDefault() != null) { | ||||||||||
| return p.getDefault().toString(); | ||||||||||
|
|
||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,7 +59,7 @@ export class Api { | |
| */ | ||
| protected ensureParamIsSet<T>(context: string, params: T, paramName: keyof T): void { | ||
| if (null === params[paramName]) { | ||
| throw new Error(`Missing required parameter ${paramName} when calling ${context}`); | ||
| throw new Error(`Missing required parameter ${String(paramName)} when calling ${context}`); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixes: |
||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -326,6 +326,11 @@ function querystringSingleKey(key: string, value: string | number | null | undef | |
| return `${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`; | ||
| } | ||
|
|
||
| export function exists(json: any, key: string) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixes: |
||
| const value = json[key]; | ||
| return value !== null && value !== undefined; | ||
| } | ||
|
|
||
| {{^withoutRuntimeChecks}} | ||
| export function mapValues(data: any, fn: (item: any) => any) { | ||
| return Object.keys(data).reduce( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,7 +13,7 @@ export function appFromJS(any: any): any { | |
| if (isIndexed(value)) { | ||
| return knownIndexedSetByKey.indexOf(key) !== -1 ? value.toSet() : value.toList(); | ||
| } // we're reviving an array -> it's a List | ||
| const MatchingType = knownRecordFactories.get(value.get('recType')) as { new(input?: any): any }; // check if we know a Record with this type | ||
| const MatchingType = knownRecordFactories.get(value.get('recType') as string) as { new(input?: any): any }; // check if we know a Record with this type | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixes |
||
| if (MatchingType) { | ||
| return new MatchingType(value); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -89,7 +89,7 @@ export function *{{nickname}}Saga() { | |
| yield takeLatest({{nickname}}, {{nickname}}SagaImp); | ||
| } | ||
|
|
||
| export function *{{nickname}}SagaImp(_action_: Action<Payload{{#lambda.titlecase}}{{#lambda.camelcase}}{{nickname}}{{/lambda.camelcase}}{{/lambda.titlecase}}>) { | ||
| export function *{{nickname}}SagaImp(_action_: Action<Payload{{#lambda.titlecase}}{{#lambda.camelcase}}{{nickname}}{{/lambda.camelcase}}{{/lambda.titlecase}}>){{^returnType}}: any{{/returnType}} { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no implicit any |
||
| const {markErrorsAsHandled, ..._payloadRest_} = _action_.payload; | ||
| try { | ||
| {{#returnTypeSupportsEntities}} | ||
|
|
@@ -233,7 +233,7 @@ export function *{{nickname}}SagaImp(_action_: Action<Payload{{#lambda.titlecase | |
| {{^returnType}} | ||
| return undefined; | ||
| {{/returnType}} | ||
| } catch (error) { | ||
| } catch (error: any) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no implicit any |
||
| if (markErrorsAsHandled) {error.wasHandled = true; } | ||
| yield put({{nickname}}Failure({error, requestPayload: _action_.payload})); | ||
| return error; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,9 @@ | ||
| {{#useAxiosHttpModule}} | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| import type { HttpService } from '@nestjs/axios'; | ||
| {{/useAxiosHttpModule}} | ||
| {{^useAxiosHttpModule}} | ||
| import type { HttpService } from '@nestjs/common'; | ||
| {{/useAxiosHttpModule}} | ||
| import { ModuleMetadata, Type } from '@nestjs/common/interfaces'; | ||
|
|
||
| export interface ConfigurationParameters { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,7 +43,7 @@ | |
| "@nestjs/testing": "~{{nestVersion}}", | ||
| "@types/express": "^4.16.0", | ||
| "@types/jest": "^24.0.15", | ||
| "@types/node": "^14.8.2", | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These types are so old that some definitions clash with the current typescript version. |
||
| "@types/node": "*", | ||
| "@types/supertest": "^2.0.8", | ||
| "concurrently": "^4.1.1", | ||
| "nodemon": "^1.19.1", | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -123,13 +123,14 @@ export type ApiKeyConfiguration = string; | |||||||
| export type HttpBasicConfiguration = { "username": string, "password": string }; | ||||||||
| export type HttpBearerConfiguration = { tokenProvider: TokenProvider }; | ||||||||
| export type OAuth2Configuration = { accessToken: string }; | ||||||||
| export type HttpSignatureConfiguration = unknown; // TODO: Implement | ||||||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not actually sure what this has to look like. Currently it's not supported as we don't have it implemented. This fix is to produce valid syntactic code, the implementation is probably a bit more involved. openapi-generator/samples/openapi3/client/petstore/typescript/builds/explode-query/auth/auth.ts Lines 164 to 166 in ce09134
|
||||||||
|
|
||||||||
| export type AuthMethodsConfiguration = { | ||||||||
| {{^useInversify}} | ||||||||
| "default"?: SecurityAuthentication, | ||||||||
| {{/useInversify}} | ||||||||
| {{#authMethods}} | ||||||||
| "{{name}}"?: {{#isApiKey}}ApiKeyConfiguration{{/isApiKey}}{{#isBasicBasic}}HttpBasicConfiguration{{/isBasicBasic}}{{#isBasicBearer}}HttpBearerConfiguration{{/isBasicBearer}}{{#isOAuth}}OAuth2Configuration{{/isOAuth}}{{^-last}},{{/-last}} | ||||||||
| "{{name}}"?: {{#isApiKey}}ApiKeyConfiguration{{/isApiKey}}{{#isBasicBasic}}HttpBasicConfiguration{{/isBasicBasic}}{{#isBasicBearer}}HttpBearerConfiguration{{/isBasicBearer}}{{#isOAuth}}OAuth2Configuration{{/isOAuth}}{{#isHttpSignature}}HttpSignatureConfiguration{{/isHttpSignature}}{{^-last}},{{/-last}} | ||||||||
| {{/authMethods}} | ||||||||
| } | ||||||||
|
|
||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -243,9 +243,12 @@ export class ResponseContext { | |
| return result; | ||
| } | ||
|
|
||
| const parameters = this.headers[headerName].split(";"); | ||
| const parameters = this.headers[headerName]!.split(";"); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is guarded further up, but some of the older TS versions we have can't determine this, yet. |
||
| for (const parameter of parameters) { | ||
| let [key, value] = parameter.split("=", 2); | ||
| if (!key) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| continue; | ||
| } | ||
| key = key.toLowerCase().trim(); | ||
| if (value === undefined) { | ||
| result[""] = key; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -65,7 +65,7 @@ type MimeTypeDescriptor = { | |
| * the payload. | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. undefined guards here too |
||
| */ | ||
| const parseMimeType = (mimeType: string): MimeTypeDescriptor => { | ||
| const [type, subtype] = mimeType.split('/'); | ||
| const [type = '', subtype = ''] = mimeType.split('/'); | ||
| return { | ||
| type, | ||
| subtype, | ||
|
|
@@ -272,7 +272,7 @@ export class ObjectSerializer { | |
| if (mediaType === undefined) { | ||
| return undefined; | ||
| } | ||
| return mediaType.split(";")[0].trim().toLowerCase(); | ||
| return (mediaType.split(";")[0] ?? '').trim().toLowerCase(); | ||
| } | ||
|
|
||
| /** | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,26 +27,26 @@ export class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{ | |
| {{/vars}} | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| {{#discriminator}} | ||
| static readonly discriminator: string | undefined = "{{discriminatorName}}"; | ||
| static {{#parent}}override {{/parent}}readonly discriminator: string | undefined = "{{discriminatorName}}"; | ||
| {{/discriminator}} | ||
| {{^discriminator}} | ||
| static readonly discriminator: string | undefined = undefined; | ||
| static {{#parent}}override {{/parent}}readonly discriminator: string | undefined = undefined; | ||
| {{/discriminator}} | ||
| {{#hasDiscriminatorWithNonEmptyMapping}} | ||
|
|
||
| static readonly mapping: {[index: string]: string} | undefined = { | ||
| static {{#parent}}override {{/parent}}readonly mapping: {[index: string]: string} | undefined = { | ||
| {{#discriminator.mappedModels}} | ||
| "{{mappingName}}": "{{modelName}}", | ||
| {{/discriminator.mappedModels}} | ||
| }; | ||
| {{/hasDiscriminatorWithNonEmptyMapping}} | ||
| {{^hasDiscriminatorWithNonEmptyMapping}} | ||
|
|
||
| static readonly mapping: {[index: string]: string} | undefined = undefined; | ||
| static {{#parent}}override {{/parent}}readonly mapping: {[index: string]: string} | undefined = undefined; | ||
| {{/hasDiscriminatorWithNonEmptyMapping}} | ||
|
|
||
| {{^isArray}} | ||
| static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ | ||
| static {{#parent}}override {{/parent}}readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ | ||
| {{#vars}} | ||
| { | ||
| "name": "{{name}}", | ||
|
|
@@ -58,7 +58,7 @@ export class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{ | |
| {{/vars}} | ||
| ]; | ||
|
|
||
| static getAttributeTypeMap() { | ||
| static {{#parent}}override {{/parent}}getAttributeTypeMap() { | ||
| {{#parent}} | ||
| return super.getAttributeTypeMap().concat({{classname}}.attributeTypeMap); | ||
| {{/parent}} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -69,7 +69,7 @@ | |
| "rxjs": "^6.4.0", | ||
| {{/useRxJS}} | ||
| {{#useInversify}} | ||
| "inversify": "^5.0.1", | ||
| "inversify": "^6.0.1", | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inversify 5.x doesn't work properly with our current TS version. It's this issue here: https://stackoverflow.com/questions/75776252/inversify-typescript-5-ts1239-unable-to-resolve-signature-of-parameter-decor |
||
| {{/useInversify}} | ||
| "es6-promise": "^4.2.4", | ||
| "url-parse": "^1.4.3" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| import { inject, injectable, multiInject, optional, interfaces } from "inversify"; | ||
|
|
||
| import { Configuration } from "../configuration"; | ||
| import { ServerConfiguration, servers } from "../servers"; | ||
| import { ServerConfiguration, servers{{#servers}}, server1{{/servers}} } from "../servers"; | ||
| import { HttpLibrary{{^useRxJS}}, wrapHttpLibrary{{/useRxJS}} } from "../http/http"; | ||
| import { Middleware{{^useRxJS}}, PromiseMiddlewareWrapper{{/useRxJS}} } from "../middleware"; | ||
| import { authMethodServices, AuthMethods } from "../auth/auth"; | ||
|
|
@@ -42,7 +42,7 @@ class InjectableConfiguration implements AbstractConfiguration { | |
| public authMethods: AuthMethods = {}; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| constructor( | ||
| @inject(AbstractServerConfiguration) @optional() public baseServer: AbstractServerConfiguration = servers[0], | ||
| @inject(AbstractServerConfiguration) @optional() public baseServer: AbstractServerConfiguration{{#servers}} = server1{{/servers}}, | ||
| @inject(AbstractHttpLibrary) @optional() httpApi: AbstractHttpLibrary, | ||
| @multiInject(AbstractMiddleware) @optional() middleware: AbstractMiddleware[] = [], | ||
| @multiInject(AbstractAuthMethod) @optional() securityConfiguration: AbstractAuthMethod[] = [] | ||
|
|
@@ -90,6 +90,9 @@ export class ApiServiceBinder { | |
| * return value; | ||
| */ | ||
| public bindServerConfigurationToPredefined(idx: number) { | ||
| if (!servers[idx]) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| throw new Error(`Server ${idx} is not available.`); | ||
| } | ||
| this.bindServerConfiguration.toConstantValue(servers[idx]); | ||
| return servers[idx]; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,22 +13,29 @@ | |
| "declaration": true, | ||
|
|
||
| /* Additional Checks */ | ||
| "noUnusedLocals": false, /* Report errors on unused locals. */ // TODO: reenable (unused imports!) | ||
| "noUnusedParameters": false, /* Report errors on unused parameters. */ // TODO: set to true again | ||
| "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ | ||
| "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ | ||
| "noUnusedLocals": false, /* Report errors on unused locals. */ // TODO: reenable (unused imports!) | ||
| "noUnusedParameters": false, /* Report errors on unused parameters. */ // TODO: set to true again | ||
| "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ | ||
| "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ | ||
| "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ | ||
| "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ | ||
| "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ | ||
|
Comment on lines
+20
to
+22
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added these three |
||
|
|
||
| "removeComments": true, | ||
| "sourceMap": true, | ||
| "outDir": "./dist", | ||
| "noLib": false, | ||
| {{#platforms}} | ||
| "lib": [ | ||
| "es6" | ||
| ,"ES2017.Object" | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. brings |
||
| ,"ES2021.String" | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| {{#node}} | ||
| "lib": [ "es6" ], | ||
| {{/node}} | ||
| {{#browser}} | ||
| "lib": [ "es6", "dom" ], | ||
| ,"dom" | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unified this, |
||
| {{/browser}} | ||
| ], | ||
| {{/platforms}} | ||
| {{#useInversify}} | ||
| "experimentalDecorators": true, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This workflow runs the type check shell file