refactor(core): Take advantage of 'assert functions' for `ngDevMode` asserts (#35964)
As of TypeScript 3.7, TypeScript supports [Assert Functions](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions). This change adds assert types to our `assert*` functions. We can't fully take advantage of this due to [Assert functions do not constraint type when they are guarded by a truthy expression.](https://github.com/microsoft/TypeScript/issues/37295) PR Close #35964
This commit is contained in:
parent
15f8afa4bf
commit
f5c7e883a9
|
@ -9,10 +9,16 @@
|
|||
import {assertDefined, assertEqual, throwError} from '../util/assert';
|
||||
|
||||
import {getComponentDef, getNgModuleDef} from './definition';
|
||||
import {LContainer} from './interfaces/container';
|
||||
import {DirectiveDef} from './interfaces/definition';
|
||||
import {TNode} from './interfaces/node';
|
||||
import {isLContainer, isLView} from './interfaces/type_checks';
|
||||
import {LView, TVIEW, TView} from './interfaces/view';
|
||||
|
||||
// [Assert functions do not constraint type when they are guarded by a truthy
|
||||
// expression.](https://github.com/microsoft/TypeScript/issues/37295)
|
||||
|
||||
|
||||
export function assertTNodeForLView(tNode: TNode, lView: LView) {
|
||||
tNode.hasOwnProperty('tView_') && assertEqual(
|
||||
(tNode as any as{tView_: TView}).tView_, lView[TVIEW],
|
||||
|
@ -50,20 +56,21 @@ export function assertDataNext(lView: LView, index: number, arr?: any[]) {
|
|||
arr.length, index, `index ${index} expected to be at the end of arr (length ${arr.length})`);
|
||||
}
|
||||
|
||||
export function assertLContainerOrUndefined(value: any): void {
|
||||
export function assertLContainerOrUndefined(value: any): asserts value is LContainer|undefined|
|
||||
null {
|
||||
value && assertEqual(isLContainer(value), true, 'Expecting LContainer or undefined or null');
|
||||
}
|
||||
|
||||
export function assertLContainer(value: any): void {
|
||||
export function assertLContainer(value: any): asserts value is LContainer {
|
||||
assertDefined(value, 'LContainer must be defined');
|
||||
assertEqual(isLContainer(value), true, 'Expecting LContainer');
|
||||
}
|
||||
|
||||
export function assertLViewOrUndefined(value: any): void {
|
||||
export function assertLViewOrUndefined(value: any): asserts value is LView|null|undefined {
|
||||
value && assertEqual(isLView(value), true, 'Expecting LView or undefined or null');
|
||||
}
|
||||
|
||||
export function assertLView(value: any) {
|
||||
export function assertLView(value: any): asserts value is LView {
|
||||
assertDefined(value, 'LView must be defined');
|
||||
assertEqual(isLView(value), true, 'Expecting LView');
|
||||
}
|
||||
|
@ -82,7 +89,7 @@ export function assertFirstUpdatePass(tView: TView, errMessage?: string) {
|
|||
* This is a basic sanity check that an object is probably a directive def. DirectiveDef is
|
||||
* an interface, so we can't do a direct instanceof check.
|
||||
*/
|
||||
export function assertDirectiveDef(obj: any) {
|
||||
export function assertDirectiveDef<T>(obj: any): asserts obj is DirectiveDef<T> {
|
||||
if (obj.type === undefined || obj.selectors == undefined || obj.inputs === undefined) {
|
||||
throwError(
|
||||
`Expected a DirectiveDef/ComponentDef and this object does not seem to have the expected shape.`);
|
||||
|
|
|
@ -7,14 +7,26 @@
|
|||
*/
|
||||
|
||||
import {assertDefined, assertEqual} from '../util/assert';
|
||||
import {TNode, TNodeType} from './interfaces/node';
|
||||
|
||||
export function assertNodeType(tNode: TNode, type: TNodeType) {
|
||||
import {TContainerNode, TElementContainerNode, TElementNode, TIcuContainerNode, TNode, TNodeType, TProjectionNode} from './interfaces/node';
|
||||
|
||||
export function assertNodeType(
|
||||
tNode: TNode, type: TNodeType.Container): asserts tNode is TContainerNode;
|
||||
export function assertNodeType(
|
||||
tNode: TNode, type: TNodeType.Element): asserts tNode is TElementNode;
|
||||
export function assertNodeType(
|
||||
tNode: TNode, type: TNodeType.ElementContainer): asserts tNode is TElementContainerNode;
|
||||
export function assertNodeType(
|
||||
tNode: TNode, type: TNodeType.IcuContainer): asserts tNode is TIcuContainerNode;
|
||||
export function assertNodeType(
|
||||
tNode: TNode, type: TNodeType.Projection): asserts tNode is TProjectionNode;
|
||||
export function assertNodeType(tNode: TNode, type: TNodeType.View): asserts tNode is TContainerNode;
|
||||
export function assertNodeType(tNode: TNode, type: TNodeType): asserts tNode is TNode {
|
||||
assertDefined(tNode, 'should be called with a TNode');
|
||||
assertEqual(tNode.type, type, `should be a ${typeName(type)}`);
|
||||
}
|
||||
|
||||
export function assertNodeOfPossibleTypes(tNode: TNode, ...types: TNodeType[]) {
|
||||
export function assertNodeOfPossibleTypes(tNode: TNode, ...types: TNodeType[]): void {
|
||||
assertDefined(tNode, 'should be called with a TNode');
|
||||
const found = types.some(type => tNode.type === type);
|
||||
assertEqual(
|
||||
|
|
|
@ -12,19 +12,20 @@
|
|||
|
||||
import {stringify} from './stringify';
|
||||
|
||||
export function assertNumber(actual: any, msg: string) {
|
||||
export function assertNumber(actual: any, msg: string): asserts actual is number {
|
||||
if (!(typeof actual === 'number')) {
|
||||
throwError(msg, typeof actual, 'number', '===');
|
||||
}
|
||||
}
|
||||
|
||||
export function assertNumberInRange(actual: any, minInclusive: number, maxInclusive: number) {
|
||||
export function assertNumberInRange(
|
||||
actual: any, minInclusive: number, maxInclusive: number): asserts actual is number {
|
||||
assertNumber(actual, 'Expected a number');
|
||||
assertLessThanOrEqual(actual, maxInclusive, 'Expected number to be less than or equal to');
|
||||
assertGreaterThanOrEqual(actual, minInclusive, 'Expected number to be greater than or equal to');
|
||||
}
|
||||
|
||||
export function assertString(actual: any, msg: string) {
|
||||
export function assertString(actual: any, msg: string): asserts actual is string {
|
||||
if (!(typeof actual === 'string')) {
|
||||
throwError(msg, actual === null ? 'null' : typeof actual, 'string', '===');
|
||||
}
|
||||
|
@ -36,13 +37,13 @@ export function assertEqual<T>(actual: T, expected: T, msg: string) {
|
|||
}
|
||||
}
|
||||
|
||||
export function assertNotEqual<T>(actual: T, expected: T, msg: string) {
|
||||
export function assertNotEqual<T>(actual: T, expected: T, msg: string): asserts actual is T {
|
||||
if (!(actual != expected)) {
|
||||
throwError(msg, actual, expected, '!=');
|
||||
}
|
||||
}
|
||||
|
||||
export function assertSame<T>(actual: T, expected: T, msg: string) {
|
||||
export function assertSame<T>(actual: T, expected: T, msg: string): asserts actual is T {
|
||||
if (!(actual === expected)) {
|
||||
throwError(msg, actual, expected, '===');
|
||||
}
|
||||
|
@ -54,25 +55,26 @@ export function assertNotSame<T>(actual: T, expected: T, msg: string) {
|
|||
}
|
||||
}
|
||||
|
||||
export function assertLessThan<T>(actual: T, expected: T, msg: string) {
|
||||
export function assertLessThan<T>(actual: T, expected: T, msg: string): asserts actual is T {
|
||||
if (!(actual < expected)) {
|
||||
throwError(msg, actual, expected, '<');
|
||||
}
|
||||
}
|
||||
|
||||
export function assertLessThanOrEqual<T>(actual: T, expected: T, msg: string) {
|
||||
export function assertLessThanOrEqual<T>(actual: T, expected: T, msg: string): asserts actual is T {
|
||||
if (!(actual <= expected)) {
|
||||
throwError(msg, actual, expected, '<=');
|
||||
}
|
||||
}
|
||||
|
||||
export function assertGreaterThan<T>(actual: T, expected: T, msg: string) {
|
||||
export function assertGreaterThan<T>(actual: T, expected: T, msg: string): asserts actual is T {
|
||||
if (!(actual > expected)) {
|
||||
throwError(msg, actual, expected, '>');
|
||||
}
|
||||
}
|
||||
|
||||
export function assertGreaterThanOrEqual<T>(actual: T, expected: T, msg: string) {
|
||||
export function assertGreaterThanOrEqual<T>(
|
||||
actual: T, expected: T, msg: string): asserts actual is T {
|
||||
if (!(actual >= expected)) {
|
||||
throwError(msg, actual, expected, '>=');
|
||||
}
|
||||
|
@ -98,7 +100,7 @@ export function throwError(msg: string, actual?: any, expected?: any, comparison
|
|||
(comparison == null ? '' : ` [Expected=> ${expected} ${comparison} ${actual} <=Actual]`));
|
||||
}
|
||||
|
||||
export function assertDomNode(node: any) {
|
||||
export function assertDomNode(node: any): asserts node is Node {
|
||||
// If we're in a worker, `Node` will not be defined.
|
||||
assertEqual(
|
||||
(typeof Node !== 'undefined' && node instanceof Node) ||
|
||||
|
|
Loading…
Reference in New Issue