Skip to content
Closed
6 changes: 6 additions & 0 deletions test-packages/typed-json-model/webapp/model/model.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import Context from "sap/ui/model/Context";
import JSONModel from "sap/ui/model/json/JSONModel";
import JSONListBinding from "sap/ui/model/json/JSONListBinding";
import {
AbsoluteBindingPath,
AbsoluteListBindingPath,
PropertyByAbsoluteBindingPath,
PropertyByRelativeBindingPath,
RelativeBindingPath,
Expand Down Expand Up @@ -57,6 +59,10 @@ export class TypedJSONModel<Data extends object> extends JSONModel {
| PropertyByRelativeBindingPath<Data, Root, Path>;
}

bindList<Path extends AbsoluteListBindingPath<Data>>(sPath: Path): JSONListBinding {
return super.bindList(sPath);
}

setData(oData: Data, bMerge?: boolean): void {
super.setData(oData, bMerge);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/

import { JSONSafe, objectLikeByInference, Placeholder } from "../input";
import JSONListBinding from "sap/ui/model/json/JSONListBinding";

import { TypedJSONModel } from "../../model";

Expand Down Expand Up @@ -76,3 +77,16 @@ import { TypedJSONModel } from "../../model";

/** @expect ts2740 */ const dataB: Array<any> = model.getData();
/** @expect ts2345 */ model.setData(dataB);

/***********************************************************************************************************************
* Check model.bindList
**********************************************************************************************************************/

/** @expect ok */ let ListBinding: JSONListBinding = model.bindList("/anArray");
Comment thread
viktorsperling marked this conversation as resolved.
Outdated
/** @expect ok */ ListBinding = model.bindList("/anArrayOfArrays/0");
/** @expect ok */ ListBinding = model.bindList("/anObjectWithArray/anArray");

/** @expect ts2345 */ ListBinding = model.bindList("/aJsonSafeArray/0");
/** @expect ts2345 */ ListBinding = model.bindList("/anArrayOfArrays/0/0");
/** @expect ts2345 */ ListBinding = model.bindList("/anObjectWithArray/anArray/0");
/** @expect ts2345 */ ListBinding = model.bindList("/anArrayOfObjects/0");
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/

import { IObjectLike, JSONSafe, objectLikeByInterface, Placeholder, TObjectLike } from "../input";
import JSONListBinding from "sap/ui/model/json/JSONListBinding";

import { TypedJSONModel } from "../../model";

Expand Down Expand Up @@ -81,3 +82,16 @@ import { TypedJSONModel } from "../../model";

/** @expect ts2740 */ const dataC: Array<any> = model.getData();
/** @expect ts2345 */ model.setData(dataC);

/***********************************************************************************************************************
* Check model.bindList
**********************************************************************************************************************/

/** @expect ok */ let ListBinding: JSONListBinding = model.bindList("/anArray");
/** @expect ok */ ListBinding = model.bindList("/anArrayOfArrays/0");
/** @expect ok */ ListBinding = model.bindList("/anObjectWithArray/anArray");

/** @expect ts2345 */ ListBinding = model.bindList("/aJsonSafeArray/0");
/** @expect ts2345 */ ListBinding = model.bindList("/anArrayOfArrays/0/0");
/** @expect ts2345 */ ListBinding = model.bindList("/anObjectWithArray/anArray/0");
/** @expect ts2345 */ ListBinding = model.bindList("/anArrayOfPlaceholders/0");
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/

import { IObjectLike, JSONSafe, objectLikeByTypeAlias, Placeholder, TObjectLike } from "../input";
import JSONListBinding from "sap/ui/model/json/JSONListBinding";

import { TypedJSONModel } from "../../model";

Expand Down Expand Up @@ -81,3 +82,16 @@ import { TypedJSONModel } from "../../model";

/** @expect ts2740 */ const dataC: Array<any> = model.getData();
/** @expect ts2345 */ model.setData(dataC);

/***********************************************************************************************************************
* Check model.bindList
**********************************************************************************************************************/

/** @expect ok */ let ListBinding: JSONListBinding = model.bindList("/anArray");
/** @expect ok */ ListBinding = model.bindList("/anArrayOfArrays/0");
/** @expect ok */ ListBinding = model.bindList("/anObjectWithArray/anArray");

/** @expect ts2345 */ ListBinding = model.bindList("/aJsonSafeArray/0");
/** @expect ts2345 */ ListBinding = model.bindList("/anArrayOfArrays/0/0");
/** @expect ts2345 */ ListBinding = model.bindList("/anObjectWithArray/anArray/0");
/** @expect ts2345 */ ListBinding = model.bindList("/anArrayOfPlaceholders/0");
9 changes: 9 additions & 0 deletions test-packages/typed-json-model/webapp/model/test/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ export interface IPrimitives {
export type TObjectLike = {
anObject: object;
anArray: Array<unknown>;
anArrayOfArrays: Array<Array<unknown>>;
aJsonSafeArray: Array<JSONSafe>;
anObjectWithArray: { anArray: Array<unknown> };
anArrayOfPlaceholders: Array<Placeholder>;
aPlaceholder: Placeholder;
aTuple: [string, number];
Expand All @@ -71,7 +73,9 @@ export type TObjectLike = {
export interface IObjectLike {
anObject: object;
anArray: Array<unknown>;
anArrayOfArrays: Array<Array<unknown>>;
aJsonSafeArray: Array<JSONSafe>;
anObjectWithArray: { anArray: Array<unknown> };
anArrayOfPlaceholders: Array<Placeholder>;
aPlaceholder: Placeholder;
aTuple: [string, number];
Expand Down Expand Up @@ -149,8 +153,13 @@ export const objectLikeByInterface: IObjectLike = {
export const objectLikeByInference = {
anObject: {},
anArray: [],
anArrayOfArrays: [
["string", 1],
[true, false],
],
aJsonSafeArray: ["string", 1, true],
anArrayOfObjects: [{ aNumber: 1 }],
anObjectWithArray: { anArray: ["string"] },
anArrayOfPlaceholders: [new Placeholder()],
aPlaceholder: new Placeholder(),
aTuple: ["string", 1],
Expand Down
13 changes: 13 additions & 0 deletions test-packages/typed-json-model/webapp/model/typing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@ export type AbsoluteBindingPath<Type> =
: // if T is not of type object:
never;

/**
* Valid absolute binding in a JSONModel with the underlying type `Type`.
* Counterpart to {@link PropertyByAbsoluteBindingPath}
* @example
* type Person = { name: string, id: number };
* type PathInPerson = PathInJSONModel<Person>; // "/name" | "/id"
* let path: PathInPerson = "/name"; // ok
* path = "/firstName"; // error
*/
export type AbsoluteListBindingPath<Type> = {
Comment thread
viktorsperling marked this conversation as resolved.
[Path in AbsoluteBindingPath<Type>]: PropertyByAbsoluteBindingPath<Type, Path> extends Array<unknown> ? Path : never;
}[AbsoluteBindingPath<Type>];

/**
* Valid relative binding path in a JSONModel.
* The root of the path is defined by the given root string.
Expand Down
Loading