delegateas / XrmDefinitelyTyped

Tool to generate TypeScript declaration files for Dynamics 365/CDS client-side coding.
http://delegateas.github.io/Delegate.XrmDefinitelyTyped/
MIT License
133 stars 53 forks source link

Error TS2688 #117

Closed sniarn closed 3 years ago

sniarn commented 5 years ago

I'm a TS noob so bear with me.

After generating the type definitions I'm unable to compile because there is no index.d.ts file being output. Running tsc gives me:

error TS2688: Cannot find type definition file for 'xrm'.

I suppose this error is caused by my type definitions being in @types\xrm, but the TypeScript compiler is unable to find an index.d.ts file in there.

My tsconfig.json looks like this:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "outDir": "./js/",
    "rootDir": "./ts/",
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "typeRoots": ["@types"],
    "types": ["xrm"],
    "esModuleInterop": true
  }
}

Is this a bug or am I just not getting it?

magesoe commented 5 years ago

Probably not a bug, but more likely a project setup error. I would seek inspiration from our project structure at https://github.com/delegateas/XrmFramework In the Webresource folder you can see our .tsconfig file

sniarn commented 5 years ago

@magesoe I tried cloning that repo and running tsc in the WebResources folder. Gives the following errors:

src/dg_XrmSolution/dg.account.ts(29,26): error TS2571: Object is of type 'unknown'.
src/dg_XrmSolution/dg.account.ts(29,58): error TS2571: Object is of type 'unknown'.
src/dg_XrmSolution/dg.account.ts(32,35): error TS2571: Object is of type 'unknown'.
src/dg_XrmSolution/dg.account.ts(33,40): error TS2571: Object is of type 'unknown'.
typings/XRM/dg.xrmquery.web.d.ts(272,19): error TS2416: Property 'handleResponse' in type 'DeleteRecord' is not assignable to the same property in base type 'Query<void>'.
  Type '(req: XMLHttpRequest, successCallback: () => any) => void' is not assignable to type '(req: XMLHttpRequest, successCallback: (t: void) => any, errorCallback: (e: Error) => any) => void'.
    Types of parameters 'successCallback' and 'successCallback' are incompatible.
typings/XRM/dg.xrmquery.web.d.ts(283,19): error TS2416: Property 'handleResponse' in type 'UpdateRecord<IUpdate>' is not assignable to the same property in base type 'Query<void>'.
  Type '(req: XMLHttpRequest, successCallback: () => any) => void' is not assignable to type '(req: XMLHttpRequest, successCallback: (t: void) => any, errorCallback: (e: Error) => any) => void'.
    Types of parameters 'successCallback' and 'successCallback' are incompatible.
../../../../../../../../usr/local/lib/node_modules/typescript/lib/lib.es2015.promise.d.ts(129,21): error TS2304: Cannot find name 'Iterable'.

The .csproj file contains some TypeScript-related nodes, so perhaps it only works when compiling from Visual Studio. I don't have access to Visual Studio right now, so I can't test it out. But it doesn't seem to be working out-of-the-box with the TypeScript compiler invoked from the command line.

magesoe commented 5 years ago

You're right that we call it from visual studio. Haven't tried running tsc without building the project first

sniarn commented 5 years ago

If that's the case then I would definitely say that this is a bug (or misbehavior) of XrmDefinitelyTyped.

magesoe commented 5 years ago

I would rather call it a problem with the project structure. XDT did generate the typings. Which version of CRM are you generating for?

sniarn commented 5 years ago

It's an on-premise CRM 365 9.0.

It seems that "normal" behavior wrt TypeScript type definitions is to grab them from npm (why not ditch NuGet?) and install the package to node_modules/@types/ where TypeScript will look by default... but that's an entirely different discussion I guess.

I got your solution working from the command line by referencing es2015.iterable and including some of the generated type definition files:

{
    "compileOnSave": true,
    "compilerOptions": {
        "target": "es5",
        "noImplicitAny": false,
        "module": "none",
        "removeComments": true,
        "declaration": false,
        "sourceMap": false,
        "noEmitOnError": false,
        "strict": true,
        "lib": [ "dom", "es5", "es2015.promise", "es2015.iterable"]
    },
    "filesGlob": [
        "**/*.ts"
    ],
    "include": [
        "typings/XRM/metadata.d.ts",
        "typings/XRM/xrm.d.ts",
    ]
}
magesoe commented 5 years ago

You can define the output directory yourself in the config of XrmDefinitelyTyped through the out argument. Wrt. npm there is already an issue on it and we're looking into it

sniarn commented 5 years ago

Thanks. I'll try to look into my .csproj file again when I'm back at work and see if I can get it working.

zhaparoff commented 5 years ago

@sniarn, I've faced the same error recently. Please refer to https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#types-typeroots-and-types for the root cause.

Possible workarounds:

  1. You should not put generated output into @types folder or any other folder, included into typeRoots - because in this case xrm definitions folder will require index.d.ts or package.json with types option defined, as entry point for definitions. And you will need to reference any single definition file from the tool output, which you are going to use in your code, in the include section of tsconfig. Most likely, this is the solution that you are already using now.

  2. Second option I can think of, can be manually adding index.d.ts to the root folder of generated output, which will have all required *.d.ts files referenced. But at the moment being, I wasn't able to make it work and don't know if it is possible at all. Also you will need to update the file every time when new entity/form is added to the generation.

Summarizing the above, any of these options will require a ton of manual work to support these solution, especially if you have 50+ entities with 2-3 forms each. And it negates all the benefits of using this tool, unfortunately =(

So currently, the best option for me is using only generic definitions (xrm, metadata), and referencing the form fields in a well-known way - by magic strings.

janis-veinbergs commented 4 years ago

@zhaparoff I also received errors like @sniarn. I may have to intro myself just like he:

I'm a TS noob so bear with me.

But I managed to get build working. First of all, I got this error when I manually specified

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

As per your info and https://github.com/microsoft/TypeScript/issues/27956 I understood that this error is spit out when it cannot find index.d.ts (not a very friendly error)

So I removed manual "types" (because TypeScript by default searches .\node_modules\@types, ..\node_modules\@types, etc.). Then I got past the Xrm error and it tried to compile my .ts but got ton of errors like this:

typings/XRM/Web/<myentity>.d.ts:238:109 - error TS2694: Namespace 'Web' has no exported member '<myentity>_Fixed'.

But after I specified this glob within include:

{
  "include": ["./my/ts/folder", "./typings/**/*"],
}

My build succeeded

misoeli commented 3 years ago

Based on most recent reply, it looks to me as if there's a way around the initial issue. Closing here.

janis-veinbergs commented 1 year ago

So there is another way where I generate index.d.ts files like as per @zhaparoff second bullet point option. I found it more appropriate when migrating type definitions to its own local npm module:

    Set-Location $modulePath

    Write-Host "Writing $((pwd).Path)\index.d.ts"
    @"
    // Generated by RunXrmDefinitelyTyped.ps1
    // https://github.com/delegateas/XrmDefinitelyTyped
    /// <reference path="./dg.xrmquery.web.d.ts" />
    /// <reference path="./metadata.d.ts" />
    /// <reference path="./xrm.d.ts" />
    /// <reference path="./Form/xrm.d.ts" />
    /// <reference path="./Web/xrm.d.ts" />
    /// <reference path="./_internal/xrm.d.ts" />
"@ | Out-File -FilePath .\index.d.ts -Force -Encoding utf8

    $FoldersToWriteIndexDTsFile = "Form", "Web", "_internal"
    $FoldersToWriteIndexDTsFile | % {
        Set-Location "$modulePath\$_"
        Write-Host "Writing $((pwd).Path)\index.d.ts"
        @"
// Generated by RunXrmDefinitelyTyped.ps1
// https://github.com/delegateas/XrmDefinitelyTyped
"@ | Out-File .\index.d.ts  -Force -Encoding UTF8
        Get-ChildItem -Filter '*.d.ts' -Name -Recurse | % {"/// <reference path=`"./$($_ -replace "\\", "/")`" />"} | Out-File -FilePath .\index.d.ts -Append -Encoding utf8
    }

And then the following works tsconfig.json, assuming $modulePath is ./modules/xrmtypings:

   "typeRoots": [
      "./node_modules/@types",
      /* XrmDefinitelyTyped typings, generated for our environmnet */
      "./modules/xrmtypings"
    ],