navigationend - Tipo de comprobación en plantillas Angular 2
title angular 6 (7)
Creo que un IDE o un linter podrían atrapar esto por ti, pero si alguien realmente lo necesita, una opción sería crear un Pipe para hacer el chequeo de tipo en tiempo de ejecución.
@Pipe({ name: ''typeCheck'' })
export class TypeCheckPipe implements PipeTransform {
transform(value: any, classType: object): any[] {
if (value &&
!(value instanceof classType)
) {
throw new TypeError("Input is not instanceof " + classType +
" but was " + typeof(value));
}
return value;
}
}
Puede usarlo en una plantilla de componentes como esta:
<custom-component [coolInput]="coolInput | typeCheck:coolInputClass"></custom-component>
La única pega que encontré es que no estoy seguro de cómo inyectar la función de clase en la plantilla que no sea como una instancia del componente.
@Component({
selector: ''my-app'',
template: `
<div>
<custom-component [coolInput]="coolInput | typeCheck:coolInputClass"></custom-component>
</div>
`,
})
export class App {
coolInput: CoolInput;
coolInputClass: object = CoolInput;
constructor() {
this.coolInput = "This is the wrong type";
}
}
Aquí hay un Plunker que ilustra el mensaje de error de trabajo (arrojado a través de la Zona). https://plnkr.co/edit/WhoKSdoKUFvNbU3zWJy6?p=preview
Estamos construyendo una aplicación en Angular 2 y TypeScript. Intentamos verificar estáticamente los tipos donde es posible. ¿Hay alguna manera de verificar los tipos en las plantillas? Considera el siguiente fragmento:
<foo [data]="dataObj"></foo>
Suponga que los data
en el componente Foo
tienen algún tipo de TData
. Sin embargo, de manera predeterminada, nada me impide pasar dataObj
que no se ajusta a TData
. ¿Hay una extensión de mecanografía para plantillas angulares que verifiquen los tipos en tal caso?
Desafortunadamente, parece que la versión angular actual no verifica tipos de entradas y eventos de componentes. Puede usar la compilación AOT y habilitar la opción del compilador angular fullTemplateTypeCheck , que realiza alguna comprobación de tipo de plantilla.
Habilite la opción fullTemplateTypeCheck en src/tsconfig.app.json
{
"compilerOptions": { ... },
"angularCompilerOptions": {
"fullTemplateTypeCheck": true
...
}
}
Y construya (o sirva) su proyecto con la opción --aot
ng build --aot
¿Qué pasa con las entradas y la comprobación de tipos de eventos? He encontrado dos problemas en el rastreador de errores angulares (número 1 y número 2). Según tengo entendido, la solución del problema depende de la implementación del renderizador, y es más probable que el problema se solucione en la próxima versión del renderizador angular, llamada Ivy . Aquí está la solicitud de características para la comprobación de tipos de entradas en el renderizador de hiedra.
Puedes usar un tubo:
export class ObjectTypePipe implements PipeTransform {
transform(value: any, args?: any): string {
if (value != undefined && value != null) {
return value.constructor.name.toString();
}
return "";
}
}
Esto luego le permitirá hacer una comparación de cadenas.
Si usa el código visual studio, puede probar la extensión del servicio lingüístico . Aún está en desarrollo, y podrías considerarlo en beta. Pero cuando definitivamente diría que me ha hecho más productivo. No solo su verificación de tipos, sino también los componentes cmd + click para ir a su fuente.
Si no me equivoco, this proyecto eventualmente se fusionará con el código propio cuando sea algo estable ya que es el mejor interés de vscode para mantener productivos a los desarrolladores angulares.
Puede estar seguro del soporte de la extensión porque el equipo angular la está trabajando. Para obtener más información, consulte este readme
Editar: el texto sublime y la tormenta web admiten esto también.
Sus componentes Input () deberían tener el tipo. Digamos que tiene un componente de lista
import {Component, Input, OnInit } from ''@angular/core'';
import { Items } from ''../../../services/Items'';
@Component({
selector: ''my-list'',
templateUrl: ''./my-list.component.html'',
styleUrls: [''./my-list.component.scss''],
})
export class CategoryListComponent implements OnInit {
@Input() items: Items;
constructor() { }
ngOnInit() { }
}
Los "elementos" se deben definir como una interfaz e importados
export interface List {
name: string,
children: Items[]
}
export interface Item {
name: string;
slug: string;
imageUrl: string;
children: Item[];
}
ahora puedes usarlo así
<my-list [items]="items"></my-list>
WebStorm de Jetbrains puede hacer eso.
Mi respuesta original:
No creo que haya una manera confiable de hacerlo sin pensar un poco como React lo hace con la extensión JSX o TSX del lenguaje.
El compilador mecanografiado no sabe acerca de sus archivos HTML, y simplemente los ignorará. Además, no existe un acoplamiento fuerte entre sus plantillas y el código del Controlador ... no hay nada que le impida reutilizar la misma plantilla en varios controladores.
Here está la documentación sobre cómo verificar los tipos usando TypeScript (desplácese hacia abajo a la sección ''Type Guards and Differentiating Types''), también here hay una respuesta detallada con un plunker que muestra cómo usar las opciones de verificación Type.
Siento que rompería el protocolo para no responder realmente la pregunta aquí dentro, así que, para ser breve, es probable que desee aprovechar las ''guardias de tipo definido por el usuario'' y la ''instancia de guardias tipo''. Tenga en cuenta que el ''instanceof type guard'' solo funciona si su Object tiene un constructor. Aquí hay un enlace al plunker de mi otra respuesta. La sección que hace todo el trabajo está en la página ''app / child.component.ts''.
ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {
console.log();
console.log("Custom function isSimpleChange:", this.isSimpleChange(changes));
console.log("Using instanceof SimpleChange:", (changes instanceof SimpleChange));
console.log("Using Object.prototype.toString.call():", Object.prototype.toString.call(changes));
console.log("Logging the object itself:",changes);
console.log("-----------------------------------------------------------------------------------------");
let testExample = new ExampleObject();
console.log("Custom function isExampleObject:", this.isExampleObject(testExample));
console.log("Using instanceof ExampleObject:", (testExample instanceof ExampleObject));
console.log("Using Object.prototype.toString.call():" + Object.prototype.toString.call(testExample));
console.log(testExample);
}