AWS CDK Not Finding Custom .d.ts files in project on Synth

673 Views Asked by At

I have a TypeScript CDK Project. Per the recommendation I read somewhere, I've put both my infrastructure and runtime code into the same project.

The runtime code is required to use an obscure js library which does not have any type definitions. I've created a custom .d.ts file with types as described here. The TypeScript compiler is happy with this and tsc builds correctly.

When however I run cdk synth I get the "Could not find a declaration file for module 'xyz'" error. I'm guessing that the CDK can't find the definition file, however it's in the same location as other .ts files.

I've edited cdk.json and removed "**/*.d.ts" from the exclude filter to no effect.

tsconfig.json:

    {
      "compilerOptions": {
        "target": "ES2020",
        "module": "commonjs",
        "lib": [
          "es2020"
        ],
        "declaration": true,
        "strict": true,
        "noImplicitAny": true,
        "strictNullChecks": true,
        "noImplicitThis": true,
        "alwaysStrict": true,
        "noUnusedLocals": false,
        "noUnusedParameters": false,
        "noImplicitReturns": true,
        "noFallthroughCasesInSwitch": false,
        "inlineSources": true,
        "experimentalDecorators": true,
        "strictPropertyInitialization": false,
        "typeRoots": [
          "./types",
          "./node_modules/@types"
        ],
        "outDir": "./out",                                   
        "esModuleInterop": true,                             
        "forceConsistentCasingInFileNames": true,            
        "sourceMap": true,                                
      },
      "include":[
        "lib",
        "bin",
        "lib/**/*",
        "bin/**/*",
        "types"
      ],
      "exclude": [
        "node_modules",
        "cdk.out",
        "./out/**/*",
        "test/**/*.spec.ts"
      ]
    }

cdk.json:

    {
      "app": "npx ts-node --prefer-ts-exts bin/LeopardGeotabApp.ts",
      "watch": {
        "include": [
          "**",
          "lib/geotab/mg-api.js.d.ts"
        ],
        "exclude": [
          "README.md",
          "cdk*.json",
          "**/*.d.ts",
          "**/*.js",
          "tsconfig.json",
          "package*.json",
          "yarn.lock",
          "node_modules",
          "test"
        ]
      },
      "build": "",
      "versionReporting": true,
      "context": {
        "@aws-cdk/aws-lambda:recognizeLayerVersion": true,
        "@aws-cdk/core:checkSecretUsage": true,
        "@aws-cdk/core:target-partitions": [
          "aws",
          "aws-cn"
        ],
        "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
        "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
        "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
        "@aws-cdk/aws-iam:minimizePolicies": true,
        "@aws-cdk/core:validateSnapshotRemovalPolicy": true,
        "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
        "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
        "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
        "@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
        "@aws-cdk/core:enablePartitionLiterals": true,
        "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
        "@aws-cdk/aws-iam:standardizedServicePrincipals": true,
        "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true
      }
    }

I'm just executing cdk synth with no parameters.

2

There are 2 best solutions below

0
On BEST ANSWER

I got around this by modifying cdk.json

{
  "app": "cp ./types/mg-api-js.d.ts ./node_modules/@types/ && npx ts-node --prefer-ts-exts bin/LeopardGeotabApp.ts && rm ./node_modules/@types/mg-api-js.d.ts",
....
}

If I didn't delete the file after the ts-node step, then if I ran tsc on its own it would fail because of the duplication of the module in the .d.ts file.

0
On

The underlying issue is that CDK uses ts-node to compile and execute your TypeScript at run-time. It makes certain optimizations under the hood to improve the speed of compilation. One of these compilation tricks is that it does not eagerly load files, include or exclude by default and resolves dependencies by import and references. This presents an issue for custom global type declarations.

Fortunately there is a solution that is documented in the ts-node README. It recognizes custom type declarations folders that you specify in typeRoots, under the condition, that you structure the folder as type packages. ts-node will not recognize loose type declaration files (./types/*.d.ts), which I believe is the root cause of your issue.

Solution

cdk.json

"compilerOptions" {
  ...
  "typeRoots": [
    "./node_modules/@types"
    "./types",
  ],
}

Folder Structure

<project_root>/
-- tsconfig.json
-- types/
  -- <module_name>/
    -- index.d.ts

Apart from these changes, no modifications need to be performed to the cdk.json file

Note: This response is my interpretation of the documentation solution from the ts-node README. Please feel free refer to it for more information on the issue