A Step-by-Step Guide on Including TypeScript Definitions in .NET Core Nuget Packages

Our internal NuGet Package includes both .NET Code and a TypeScript Definition File (*.d.ts). Here is what the package contains:

https://i.sstatic.net/7vRxx.png

Upon installation of the package into a new .NET Core project, the solution explorer displays the following folder structure.

https://i.sstatic.net/Wmn2E.png

Although everything appeared to be in order, there are small arrow symbols on the "i18n" folder and the "Index.d.ts" file, indicating that they may just be links to the actual files. While the d.ts file content appears correct when clicked on, Visual Studio fails to recognize the declarations within, making it unusable in our TypeScripts.

We considered adding the path to the packages in tsconfig.json as a potential solution, but we're seeking alternative ideas. Any suggestions?

Answer №1

Upon reviewing the responses here and persevering, I feel compelled to share my unique approach.

Working on a complex solution with over 100 subprojects, many of which involve rapidly changing NuGets, I was determined not to give up. My goal was to have my .NET object models, along with their interface/class representations in TypeScript, accessible through a single NuGet package to streamline dependency management. It's worth noting that I tested this method solely with my own object model, free from external dependencies, and exclusively in VS2022.

In this controlled scenario, everything functioned flawlessly without any hitches.

For the project containing the TS definitions:

Specify the build action for the necessary ts definitions to be included in the NuGet as "content." This will ensure they are packaged within the NuGet.

For the consumer side:

Adjust your package reference and add the following property/value:

<GeneratePathProperty>True</GeneratePathProperty>

This will create an MsBuild property referencing the local path where the restored NuGet file resides (crucial for builds across multiple machines like CI pipelines and build servers), eliminating the need for hardcoded absolute paths.

The generated property follows this format:

$(Pkg<PackageNameWithDotsBeingReplacedByUnderlines>)

Thus, a package named "MyPackage.Hello" would result in the variable $(PkgMyPackage_Hello).

Next, establish a new build target to copy files from the contentfiles folder of the restored package (now that it's restored, we can pinpoint the extracted path).

<Target Name="CopyImportedTypes" BeforeTargets="Build">
  <ItemGroup>
      <TsTypesToCopy Include="$(PkgMyPackage_Hello)\contentFiles\any\net6.0-windows10.0.20348\*.ts" />
   </ItemGroup>
   <Copy SourceFiles="@(TsTypesToCopy)" DestinationFolder="$(MSBuildProjectDirectory)\AnyProjectSubFolderIfDesired" SkipUnchangedFiles="true" OverwriteReadOnlyFiles="true" />
</Target>

Be sure to customize the "Include" path according to your package (TFM, Platform, etc.). A convenient method to obtain the relative path is by navigating to the consuming project in Solution Explorer, expanding dependencies and packages, accessing the properties of the package containing your ts definitions, and examining the contentfiles.

This target runs before the actual build process (allowing immediate use of imported types) thanks to the BeforeTargets property. The ItemGroup defines items (such as source files) stored in @(TsTypesToCopy), utilized by the copy task.

Fortunately, VS typically assigns newly added files the correct build action automatically, so the fresh ts files should require no manual adjustments.

Answer №2

Guide on Integrating TypeScript Definitions into .NET Core Nuget Packages

From what I understand, Definitely Typed packages may not work seamlessly with .NET Core projects because the script files need to be added within the <contentFiles> element. For more detailed information, you can check out the Including content files documentation.

In addition, like Martin mentioned, using npm is the preferred way to install Definitely Typed packages:

https://github.com/DefinitelyTyped/DefinitelyTyped#how-do-i-get-them

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

In Vue 3, the v-model feature is utilized as parameter passing instead of using :prop and @emit

I've been trying to implement two-way binding using v-model in Vue.js based on this article. The idea is to pass values from a parent component to a child component with automatic event emission when the value changes in the child component. However, ...

What is the best way to reference a module within my own code in TypeScript running on Node.js

Currently, I have two modules named 'json' and 'json-object'. The 'json' module consists of all objects extending the default JSON object in JSON format: import { JSONObject } from './json-object'; export abstract ...

The automatic type inference in Typescript is faulty

I am currently working with TypeScript version ^4.1.3 and have developed a REST API that deals with albums and art collections. Before sending the response to the web client, I make sure to remove the userId property from the collections. Below are my Alb ...

What is the process for importing a JSON5 file in Typescript, just like you would with a regular JSON file?

I am looking to import a JSON5 file into a JavaScript object similar to how one can import a JSON file using [import config from '../config.json']. When hovering over, this message is displayed but it's clearly visible. Cannot find module & ...

Developing a bespoke React Typescript button with a custom design and implementing an onClick event function

Currently, I am in the process of developing a custom button component for a React Typescript project utilizing React Hooks and Styled components. // Button.tsx import React, { MouseEvent } from "react"; import styled from "styled-components"; export int ...

Do I still need to use @types/core-js for TypeScript typings in a Node.js application?

I manage multiple Node.js projects that focus on backend development and utilize a straightforward TypeScript setup. Prior to March 2018, my package.json file included the following: "devDependencies": { "@types/core-js": "^0.9.46", "@types/nod ...

React - All subsequent variable declarations must be of the same type

Running webpack in my React application results in the following error message appearing 58 times across different variables: https://i.sstatic.net/uedR7.png Removing the @types directory did not resolve the issue and instead produced a new error message: ...

Is there a way to access the value of a public variable within the @input decorator of a function type?

I am working on a dropdown component that utilizes the @Input decorator to define a function with arguments, returning a boolean value. dropdown-abstract.component.ts @Input() public itemDisabled: (itemArgs: { dataItem: any; index: number }) => boo ...

Is it possible to define a class prior to exporting it in typescript/angular? | TSLint warning: unused expression, assignment or function call expected

Coming from the realm of React, I am well-versed in the fundamental concepts of launching an application with an index.js, avoiding direct involvement with HTML, and utilizing import and export statements to share views among different JavaScript files. In ...

The shared service is malfunctioning and displaying inconsistent behavior

app.component.ts import { Component } from '@angular/core'; import { HeroService } from './hero.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.compon ...

Tips for sending the image file path to a React component

Hey, I'm working on a component that has the following structure: import React from "react"; interface CInterface { name: string; word: string; path: string; } export function C({ name, word, path }: CInterface) { return ( < ...

The issue with .NET Core - SerializerSettings not taking effect

Configuration.cs services.AddMvc().AddJsonOptions(config => { config.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; }); DataConverter class JsonConvert.SerializeObject(dataObject) The SerializerSettings ...

What is the best way to perform unit testing on a function component that includes React.useState() using jest and enzyme?

I'm working on a function component that utilizes React.useState() to handle the state of a drawer modal. My challenge lies in testing this function and its ability to modify state using jest enzyme, as I cannot access its state function due to it not ...

Visualizing hierarchical data in Angular 12 using D3 tree with clickable navigation links

I'm facing a challenge in displaying a routerLink within my d3.tree(). I've attempted to do so like this: .append("a") .html(`<a [routerLink]="/mycomponent" fragment="1.1">link to user component</a>`); However, the following code wor ...

The code is looking for an assignment or function call, but found an expression instead: no-unused-expressions

Why am I encountering an ESLint error when using Ternary with 2 statements here? ESLint Error: no-unused-expressions res?.isSuccessful ? (this.toastService.showToast(res.message, 'success'), this.queueDataService.addMember(attendee)) : ...

Creating an interface in Dart: Step-by-step guide to defining interfaces similar to TypeScript

Coming from a Typescript background, I used to define object interfaces like this: export interface Locale { login: { title: string; actions: { submit: string; forgot: string; } } } However, in Dart, interfaces are implicit an ...

Exploring ways to retrieve and manipulate variables from different components in Angular

Currently working on an Angular app using TypeScript: The app.component features a top navigation bar, followed by the router-outlet for other components <navigation></navigation> <router-outlet></router-outlet> Navigation Sectio ...

Can someone guide me on identifying the type of object in React/Typescript?

Can anyone help me remove this unnecessary definition? const [nextLocation, setNextLocation] = useState(null) as any[]; I have been struggling with this in my React Router 6 project. I've looked through the documentation but haven't found a suit ...

Sending Component Properties to Objects in Vue using TypeScript

Trying to assign props value as an index in a Vue component object, here is my code snippet: export default defineComponent({ props:{ pollId:{type: String} }, data(){ return{ poll: polls[this.pollId] } } }) Encountering errors wh ...

Using TypeScript to patiently wait for an observable or promise to complete before returning an observable

As a newcomer to TypeScript & RxJS, my goal is to return an Observable once another Observable has completed: public myObservable = () : Observable<boolean> => { console.log('Retrieving the token from the database'); return ...