SOLVED

Typings vs @types for SPFx - what is the guidence for referencing other javascript frameworks?

Copper Contributor

I was following a guide to implement handlebars in my SPFx web part, and it referenced using 

typings install dt~handlebars --save --global

 to add the handlebars reference in typescript. However the Typescript blog post at https://blogs.msdn.microsoft.com/typescript/2016/06/15/the-future-of-declaration-files/ indicated that using the '@types' approach is the recommended one, and even the 'typings' github page has it marked as deprecated. However using this approach via

 

 

npm install --save-dev @types/handlebars

produces an error when

gulp serve

or

gulp build

is run after adding the code to import it into Typescript code via (for example).

import * as Handlebars from 'handlebars';

Is this a known issue with just Handlebars? Because i think I also hit a similar issue with jquery but am still investigating.

 

What is the official guidance for using 3rd party frameworks? Are these transitional errors or is there something specific in the architecture of '@types' that makes it incompatible and thus the need to still use 'typings'?

 

1 Reply
best response confirmed by Nissan Dookeran (Copper Contributor)
Solution

TL;DR

Use @types... Typings is the older way of getting type definitions prior to TypeScript v2.x.

 

More:

Definitely Typed (http://definitelytyped.org) (DT) is the primary source for all type definitions when a package does not include the type definition within it (as more and more do these days... you can check by looking at the package.json of the NPM module you are importing... if there's a "typings" property, the library has its own type definition).

 

Initially, we used a tool called TSD to acquire and manage type definitions from DT. That was replaced by Typings. When TypeScript 2.x shipped, it introduced type definition management via scoped NPM packages... in this case, @types is the scope.

 

At the same time, Microsoft contributed a project (http://microsoft.github.io/TypeSearch) that monitors additions & updates to type def's in DT. When it sees one, it pulls it down and creates / updates a new NPM package for that type definition (ex: https://www.npmjs.com/package/@types/jquery).

 

This way, a single NPM INSTALL command will get all the packages necessary + type definitions.

 

Specifically for your example, Handlebars doesn't export a top level object named Handlebars... it's exported as a namespace... so you can just import the parts you are looking for. Like:

import { registerHelper } from 'handlebars';
registerHelper(something, () => { }, true);

 

Or you can alias the whole thing like this:
import * as Handlebars from "handlebars";
Handlebars.registerHelper(something, () => { }, true);

 

Ref:

https://blogs.msdn.microsoft.com/typescript/2016/06/15/the-future-of-declaration-files

1 best response

Accepted Solutions
best response confirmed by Nissan Dookeran (Copper Contributor)
Solution

TL;DR

Use @types... Typings is the older way of getting type definitions prior to TypeScript v2.x.

 

More:

Definitely Typed (http://definitelytyped.org) (DT) is the primary source for all type definitions when a package does not include the type definition within it (as more and more do these days... you can check by looking at the package.json of the NPM module you are importing... if there's a "typings" property, the library has its own type definition).

 

Initially, we used a tool called TSD to acquire and manage type definitions from DT. That was replaced by Typings. When TypeScript 2.x shipped, it introduced type definition management via scoped NPM packages... in this case, @types is the scope.

 

At the same time, Microsoft contributed a project (http://microsoft.github.io/TypeSearch) that monitors additions & updates to type def's in DT. When it sees one, it pulls it down and creates / updates a new NPM package for that type definition (ex: https://www.npmjs.com/package/@types/jquery).

 

This way, a single NPM INSTALL command will get all the packages necessary + type definitions.

 

Specifically for your example, Handlebars doesn't export a top level object named Handlebars... it's exported as a namespace... so you can just import the parts you are looking for. Like:

import { registerHelper } from 'handlebars';
registerHelper(something, () => { }, true);

 

Or you can alias the whole thing like this:
import * as Handlebars from "handlebars";
Handlebars.registerHelper(something, () => { }, true);

 

Ref:

https://blogs.msdn.microsoft.com/typescript/2016/06/15/the-future-of-declaration-files

View solution in original post