2015-11-12 4 views
30

Мы создаем приложение в Angular 2 и TypeScript. Мы стараемся статически проверять типы, где это возможно. Есть ли способ проверить типы в шаблонах? Рассмотрим следующий фрагмент:Проверка типов в шаблонах Angular 2

<foo [data]="dataObj"></foo> 

Предположим, что data в Foo компонент имеет некоторый тип TData. Однако по умолчанию ничто не мешает мне пройти dataObj, который не соответствует TData. Существует ли расширение для шаблонов с угловым шаблоном, которое проверяет типы в таком случае?

+2

В настоящее время нет ни одного "p lugin ", который делает это (для этого вам понадобится машинопись). Angular2 приложил много усилий, чтобы сделать свой код и шаблоны доступными для IDE, но это будущее. – gilamran

+0

@gilamran Как мне это сделать даже с использованием TypeScript? –

+1

Подумав об этом немного, может быть, решение будет оберточной функцией? что-то вроде ' Scrambo

ответ

-3

Here - это документация о том, как проверить типы с использованием TypeScript (прокрутите вниз до раздела «Типы и типы дифференциации»), а также here - подробный ответ с помощью плункера, в котором показано, как использовать параметры проверки типа.

Я чувствую, что я нарушаю протокол, чтобы не отвечать на вопрос внутри, поэтому, чтобы быть кратким, вы, скорее всего, захотите воспользоваться преимуществами «Защищенных пользователем типов» и «Защитными элементами типа instanceof» ». Обратите внимание, что «защита типа instanceof» работает только в том случае, если у объекта Object есть конструктор. Вот ссылка на plunker из моего другого ответа. Раздел, выполняющий всю работу, находится на странице «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); 
} 
+1

Это не то, о чем я прошу в этом вопросе, - я хочу, чтобы проверка типов времени компиляции самих шаблонов. Вы показываете, как регистрировать во время выполнения тип любого объекта в машинописном коде. – jfu

1

Я думаю, IDE или ЛИНТЕР может поймать это для вас, но если кто-то действительно нуждается в этом, один из вариантов было бы создать трубы, чтобы сделать проверку типа во время выполнения.

@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; 
    } 
} 

Вы можете использовать его в шаблоне компонента, как это:

<custom-component [coolInput]="coolInput | typeCheck:coolInputClass"></custom-component> 

Единственная загвоздка я обнаружил, что я не уверен, как придать функции класса в шаблон, кроме как экземпляр компонента.

@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"; 
    } 
} 

Здесь представлен Plunker, иллюстрирующий сообщение об ошибке работы (выбрасывается через зону). https://plnkr.co/edit/WhoKSdoKUFvNbU3zWJy6?p=preview

+1

Вопрос о проверке этого статически, а не во время выполнения. – jfu

+0

О, я вижу. Думал, что это странная просьба. Я считаю, что вы не можете сделать это с помощью машинописи. Вам нужен дополнительный инструмент для проверки файлов шаблонов, так как они не обрабатываются машинописными текстами. Возможно, как линтер. Тем не менее, я не знаю инструмента, который в настоящее время проверяет типы входных сигналов углового2. – kevinrstone

+0

Linter не поймает это для вас. – Mozgor

0

Если вы используете визуальный код студии, вы можете попробовать расширение language service. Он все еще находится в тяжелом развитии, и вы можете рассмотреть его в бета-версии. Но когда я определенно скажу, что это сделало меня более продуктивным. Не только проверка типа, но и cmd + щелчок компонентов, чтобы перейти к их источнику.

Если я не ошибаюсь, проект this в конечном итоге будет объединен, чтобы встраивать его сам, когда он несколько стабилен, так как он наилучшим образом заинтересован в том, чтобы угловые разработчики производили.

Вы можете быть уверены, что их удерживает дополнительная поддержка, потому что на это работает угловая команда. Для получения дополнительной информации ознакомьтесь с этим readme

Редактировать: возвышенный текст и поддержка веб-сервера тоже.

-1

WebStorm от Jetbrains может это сделать.

Мой первоначальный ответ:

Я не думаю, что есть надежный способ сделать это, не делая некоторые думать, как Реагировать делает с расширением JSX или TSX к языку.

Компилятор typescript не знает о ваших файлах HTML и будет игнорировать их . Кроме того, нет сильной связи между вашими шаблонами и кодом контроллера ... нет ничего, что помешало бы вам повторно использовать один и тот же шаблон на нескольких контроллерах .

+0

Теперь есть AOT, который учитывает шаблоны. – jfu

+0

Кроме того, только что заметили, что WebStorm от Jetbrains способен проверять типы переменных на шаблонах. –

0

Ваши компоненты Вход() должен иметь тип. Допустим, у вас есть список компонентов

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() { } 
} 

«Элементы» должен быть определен как интерфейс, так и импортного

export interface List { 
    name: string, 
    children: Items[] 
} 

export interface Item { 
    name: string; 
    slug: string; 
    imageUrl: string; 
    children: Item[]; 
} 

теперь вы можете использовать его как этот

<my-list [items]="items"></my-list> 
0

Вы можете использовать Труба:

export class ObjectTypePipe implements PipeTransform { 

    transform(value: any, args?: any): string { 

     if (value != undefined && value != null) { 
      return value.constructor.name.toString(); 
     } 
     return ""; 
    } 
}