Usando el plugin jQuery en TypeScript

Cuando uso typescript, ¿necesito importar un plugin.d.ts por cada js externo que uso? En otras palabras, ¿necesito crear un jQuery.d.ts con todas las interfaces?

El problema con los complementos de jQuery (y otras bibliotecas basadas en complementos) es que no solo necesita un archivo library.d.ts para la biblioteca base, sino que también necesita un archivo plugin.d.ts para cada complemento. Y de alguna manera, los archivos plugin.d.ts deben ampliar las interfaces de la biblioteca definidas en los archivos library.d.ts. Afortunadamente, TypeScript tiene una pequeña característica ingeniosa que te permite hacer precisamente eso.

Con las classes , actualmente solo puede haber una definición conónica única de una clase dentro de un proyecto. Entonces, si defines una class Foo los miembros que colocas en Foo son todo lo que obtienes. Cualquier definición adicional de Foo dará como resultado un error. Sin embargo, con las interfaces , los miembros son aditivos, por lo que si define la interface Bar con un conjunto de miembros, puede definir ‘Barra de interfaz’ por segunda vez para agregar miembros adicionales a la interface . Esa es la clave para admitir complementos jQuery de una manera fuertemente tipada.

Por lo tanto, para agregar soporte para un plugin de jQuery determinado, necesitará crear un archivo plugin.d.ts para el plugin que quiera usar. Usamos plantillas jQuery en nuestro proyecto, así que aquí está el archivo jquery.tmpl.d.ts que creamos para agregar soporte para ese complemento:

 interface JQuery { tmpl(data?:any,options?:any): JQuery; tmplItem(): JQueryTmplItem; template(name?:string): ()=>any; } interface JQueryStatic { tmpl(template:string,data?:any,options?:any): JQuery; tmpl(template:(data:any)=>string,data?:any,options?:any): JQuery; tmplItem(element:JQuery): JQueryTmplItem; tmplItem(element:HTMLElement): JQueryTmplItem; template(name:string,template:any): (data:any)=>string[]; template(template:any): JQueryTemplateDelegate; } interface JQueryTemplateDelegate { (jQuery: JQueryStatic, data: any):string[]; } interface JQueryTmplItem { data:any; nodes:HTMLElement[]; key:number; parent:JQueryTmplItem; } 

Rompiendo esto, lo primero que hicimos fue definir los métodos que se agregan a la interfaz de JQuery . Estos le permiten obtener intellisense y verificar tipos cuando escribe $('#foo').tmpl(); A continuación, añadimos métodos a la interfaz JQueryStatic que aparecen cuando escribe $.tmpl(); Y finalmente, el plugin de jQuery Templates define algunas de sus propias estructuras de datos, por lo que necesitábamos definir interfaces para esas estructuras.

Ahora que tenemos las interfaces adicionales definidas, solo necesitamos referenciarlas desde los archivos .ts consumidores. Para hacer eso, simplemente agregamos las referencias a continuación a la parte superior de nuestro archivo .ts y eso es todo. Para ese archivo, TypeScript verá los métodos jQuery base y los métodos de complemento. Si usa varios complementos, asegúrese de referir todos sus archivos plugin.d.ts individuales y debería estar bien.

 ///  ///  

Guardar un archivo .ts no desencadena automáticamente la comstackción en Visual Studio. Tendrá que construir / reconstruir para activar la comstackción.

Los archivos de statement (archivo.d.ts) le permiten al comstackdor de TypeScript obtener mejor información de tipo sobre las bibliotecas de JavaScript que está utilizando desde ese archivo. Puede hacer que sus interfaces se definan en un solo archivo o en varios archivos; esto no debería hacer ninguna diferencia. También puede “declarar” los tipos / variables que está utilizando desde bibliotecas externas usando algo como:

 declare var x: number; 

que le dirá al comstackdor que trate x como un número.

He estado buscando un d.ts para jquery.inputmask y finalmente he creado uno simple. Está en

https://github.com/jpirok/Typescript-jquery.inputmask

o puedes ver el código a continuación.

No cubrirá todos los casos para jquery.inputmask, pero probablemente manejará la mayoría.

  /// interface JQueryInputMaskOptions { mask?: string; alias?: string; placeholder?: string; repeat?: number; greedy?: boolean; skipOptionalPartCharacter?: string; clearIncomplete?: boolean; clearMaskOnLostFocus?: boolean; autoUnmask?: boolean; showMaskOnFocus?: boolean; showMaskOnHover?: boolean; showToolTip?: boolean; isComplete?: (buffer, options) => {}; numeric?: boolean; radixPoint?: string; rightAlignNumerics?: boolean; oncomplete?: (value?: any) => void; onincomplete?: () => void; oncleared?: () => void; onUnMask?: (maskedValue, unmaskedValue) => void; onBeforeMask?: (initialValue) => void; onKeyValidation?: (result) => void; onBeforePaste?: (pastedValue) => void; } interface inputMaskStatic { defaults: inputMaskDefaults; isValid: (value: string, options: inputMaskStaticDefaults) => boolean; format: (value: string, options: inputMaskStaticDefaults) => boolean; } interface inputMaskStaticDefaults { alias: string; } interface inputMaskDefaults { aliases; definitions; } interface JQueryStatic { inputmask: inputMaskStatic; } interface JQuery { inputmask(action: string): any; inputmask(mask: string, options?: JQueryInputMaskOptions): JQuery; } 

Antes de crear su propio archivo .d.ts para el complemento, debe verificar si ya se trata de una biblioteca DefinitelyTyped . Por ejemplo, usando Typings , puede ejecutar el comando:

 typings install dt~bootstrap --global --save 

… y sin ningún código adicional, tendrás acceso a los diversos complementos de Bootstrap.

Si no tienen el complemento que está buscando, considere contribuir con su propia definición.

Usar un archivo de statement .d.ts es probablemente mejor, pero como alternativa también puede usar la combinación de aumento y statement global de TypeScript para agregar métodos a la interfaz de JQuery. Puede colocar algo como lo siguiente en cualquiera de sus archivos de TypeScript:

 declare global { interface JQuery { nameOfPluginMethod(arg: any): JQuery; } }