Проблема Angular4 HttpClient TypeCheck
Я читал, что HttpClient нового Angular может выполнять TypeChecking, основываясь на том, что я пишу следующий код
post(path: string, body: Object = {}): Observable<ValorTest> {
return this.http.post<ValorTest>(path, JSON.stringify(body))
.map((data: ValorTest) => {
console.log(typeof data); // Why console displays 'data' as object instead of ValorTest?
console.log(data instanceof ValorTest); // outputs: false
console.log(data); // outputs (no type displayed in Chrome's console): {codigo: "INF00001", estado: "Success"}
})
.pipe(catchError(this.formatErrors));
}
Я получаю JSON, который соответствует моему классу модели (ValorTest).
Вопрос: почему console.log отображает тип данных как объект вместо ValorTest?
3 ответа
Если вы просто проверяете / проверяете тип, вы можете использовать instanceof. Если вам действительно нужно напечатать имя класса, вы можете попробовать data.constructor.name:
class TestClass {}
var instance = new TestClass();
console.log(typeof instance);
// Expected output: "object"
console.log(instance.constructor.name);
// Expected output: "TestClass"
if (instance instanceof TestClass) {
console.log("instance is TestClass");
}
// Expected output: "instance is TestClass"
Что касается причины: typeof работает только со встроенными в JavaScript типами данных, такими как string, boolean, object и т. Д. Если вы посмотрите, как TypeScript переносится в JavaScript, вы можете понять, почему во время выполнения JavaScript знает только, что ваш экземпляр это "объект".
обновленный
Это будет работать только на экземплярах, созданных с помощью нового конструктора class(). HttpClient на самом деле не создает здесь экземпляр вашего класса - он просто позволяет вам (в целях разработки) указать с помощью TypeScript тип данных, которые вы ожидаете получить в ответе. Насколько я знаю, HttpClient не делает ничего, чтобы гарантировать (во время выполнения), что данные ответов действительно соответствуют этим ожиданиям. Если вам требуется строгая проверка типов во время выполнения, вам, вероятно, потребуется написать собственную функцию защиты типов.
Так что, если у вас был такой класс:
class TestClass {
prop: string;
constructor() { }
method(): void {}
}
Вы могли бы написать охранник типа как это:
function isTestClass(obj: TestClass | object): obj is TestClass {
// add whatever type checking logic you need here
return (<TestClass>obj).method !== undefined &&
(<TestClass>obj).prop !== undefined;
}
И проверьте ваши данные во время выполнения:
var obj_a = { prop: "" },
obj_b = { prop: "", method: null };
console.log(isTestClass(obj_a));
// Expected output: false
console.log(isTestClass(obj_b));
// Expected output: true
Я мог бы сделать функцию защиты типов статическим методом моего класса.
Кроме того, помимо этого, вы можете рассмотреть возможность использования интерфейса для данных ответа вместо класса - в основном потому, что это может помочь интуитивно понять, что полученные вами данные могут иметь или не иметь реализацию, которую вы ожидаете.
Подробнее о защите пользовательских типов по адресу: https://www.typescriptlang.org/docs/handbook/advanced-types.html
typeof
call будет испускать только встроенные типы JS, что вы, вероятно, хотите сделать, это проверить instanceof
, который скажет вам, если возвращаемое значение соответствует вашему пользовательскому типу!
Не относящиеся к HttpClient, все коды и типы машинописного текста преобразуются в javascript, который браузер может скомпилировать, затем javascript обрабатывает их с помощью объектов, поэтому в консоли он просто знает объекты.