//////////////////////////////// // variable tests and definitions interface User { firstName: string age: number address: Address } interface Address { street: string } interface MappedUser { firstName: KnockoutObservable age: KnockoutObservable address: MappedAddress } interface MappedAddress { street: KnockoutObservable } interface Car { name: string maintenance: ReadonlyArray drivers: User[] } interface MappedCar { name: KnockoutObservable maintenance: KnockoutReadonlyObservableArray drivers: KnockoutObservableArray } let badUserMappingOptions: KnockoutMappingOptions = { ignore: ['age'], include: ['name'], copy: ['height'], mappedProperties: ['age', 'name'], deferEvaluation: false, create: (options: KnockoutMappingCreateOptions) => { }, // $ExpectError } let userMappingOptions: KnockoutMappingOptions = { ignore: ['age'], include: ['name'], copy: ['height'], mappedProperties: ['age', 'name'], deferEvaluation: false, firstName: { create: (options: KnockoutMappingCreateOptions) => { } }, } let badMapping = { ignof3efere: ['age'], inclfefeude: ['name'], } //////////////////////////////// // fromJS function with JS object without Array properties let userInput: User = { firstName: 'foo', age: 12, address: { street: 'street name' } } let mappedUserViewModel: MappedUser = mapping.fromJS(userInput) // $ExpectType KnockoutObservableType mappedUserViewModel.age // $ExpectType KnockoutObservable mapping.fromJS(userInput, {}) // $ExpectType KnockoutObservableType mapping.fromJS(userInput, {}, mappedUserViewModel) // $ExpectType KnockoutObservableType mapping.fromJS(userInput, mappedUserViewModel) // $ExpectType KnockoutObservableType mapping.fromJS(userInput, userMappingOptions, mappedUserViewModel) // $ExpectType KnockoutObservableType mapping.fromJS(userInput, {}, userInput) // $ExpectError mapping.fromJS(userInput, userInput) // $ExpectError let untypedObject: any = { age: 22 } mapping.fromJS(untypedObject) // $ExpectType any //////////////////////////////// // fromJS function with JS object with Array properties let carInput: Car = { name: 'hb20x', maintenance: [1, 2], drivers: [userInput] } let mappedCar: MappedCar = mapping.fromJS(carInput) let drivers: KnockoutObservableArray = mappedCar.drivers let maintenance: KnockoutReadonlyObservableArray = mappedCar.maintenance //////////////////////////////// // fromJS function with primitives let numberInput: number let stringInput: string let booleanInput: boolean let symbolInput: symbol mapping.fromJS(numberInput) // $ExpectType KnockoutObservable mapping.fromJS(stringInput) // $ExpectType KnockoutObservable mapping.fromJS(symbolInput) // $ExpectType KnockoutObservable // Typescript weirdly returns KnockoutObservable | KnockoutObservable let booleanMapped: KnockoutObservable = mapping.fromJS(booleanInput) //////////////////////////////// // fromJS function with JS Array let userArrayInput = [userInput] let untypedArrayObject: any[] let numberArrayInput: number[] mapping.fromJS(userArrayInput) // $ExpectType KnockoutObservableArray> mapping.fromJS(userArrayInput, {}) // $ExpectType KnockoutObservableArray> mapping.fromJS(userArrayInput, {}, userArrayInput) // $ExpectError // Could not solve this issue. Could not get his to return any when T is any. It returns a Union type of the possible values. mapping.fromJS(untypedArrayObject) // $ExpectType KnockoutObservableArray | KnockoutObservableArray> let mappedNumberArrayViewModel = mapping.fromJS(numberArrayInput) // $ExpectType KnockoutObservableArray mapping.fromJS(numberArrayInput, {}, mappedNumberArrayViewModel) // $ExpectType KnockoutObservableArray mapping.fromJS(numberArrayInput, mappedNumberArrayViewModel) // $ExpectType KnockoutObservableArray //////////////////////////////// // fromJS function with JS ReadonlyArray let userReadonlyArrayInput: ReadonlyArray let numberReadonlyArray: ReadonlyArray mapping.fromJS(userReadonlyArrayInput) // $ExpectType KnockoutReadonlyObservableArray> mapping.fromJS(userReadonlyArrayInput, {}) // $ExpectType KnockoutReadonlyObservableArray> mapping.fromJS(userReadonlyArrayInput, {}, userArrayInput) // $ExpectError let mappedNumberReadonlyArrayViewModel = mapping.fromJS(numberReadonlyArray) // $ExpectType KnockoutReadonlyObservableArray mapping.fromJS(numberReadonlyArray, {}, mappedNumberReadonlyArrayViewModel) // $ExpectType KnockoutReadonlyObservableArray mapping.fromJS(numberReadonlyArray, mappedNumberReadonlyArrayViewModel) // $ExpectType KnockoutReadonlyObservableArray //////////////////////////////// // fromJSON function interface nameObject { name: string } let nameObjectInput: nameObject = { name: 'bar' } let nameObjectInputJSON = '{ name: "foo" }' mapping.fromJSON(nameObjectInputJSON) // $ExpectType any mapping.fromJSON(nameObjectInputJSON, {}) // $ExpectType any mapping.fromJSON(nameObjectInputJSON, nameObjectInput) // $ExpectType any mapping.fromJSON(nameObjectInputJSON, {}, nameObjectInput) // $ExpectType any let userInputJSON = "{ firstName: 'foo', age: 12 }" mapping.fromJSON(userInputJSON, userMappingOptions, mappedUserViewModel) // $ExpectType any //////////////////////////////// // toJS function mapping.toJS(mappedUserViewModel) // $ExpectType User mapping.toJS(mappedUserViewModel, {}) // $ExpectType User // Here the method isn't typed literally, it has implicit type. Unfortunatly the typing fails to properly type object properties that are object themselves. // Could not solve this issue. let unmmapedUser: User = mapping.toJS(mappedUserViewModel) // $ExpectError mapping.toJS(mappedUserViewModel) // $ExpectError mapping.toJS(stringInput) // $ExpectError mapping.toJS(ko.observable(2)) // $ExpectType number mapping.toJS(mappedNumberArrayViewModel) // $ExpectType number[] mapping.toJS(untypedObject) // $ExpectType any mapping.toJS(ko.observableArray(untypedArrayObject)) // $ExpectType any[] //////////////////////////////// // toJSON function mapping.toJSON(nameObjectInput) // $ExpectType string mapping.toJSON(nameObjectInput, {}) // $ExpectType string mapping.toJSON(mappedUserViewModel, userMappingOptions) // $ExpectType string //////////////////////////////// // visitModel function mapping.visitModel(nameObjectInput, (x: any) => x, {}) mapping.visitModel(nameObjectInput, (x: any) => x, { visitedObjects: null }) mapping.visitModel(nameObjectInput, (x: any) => x, { parentName: 'parent' }) mapping.visitModel(nameObjectInput, (x: any) => x, { ignore: ['age'] }) mapping.visitModel(nameObjectInput, (x: any) => x, { copy: ['height'] }) mapping.visitModel(nameObjectInput, (x: any) => x, { include: ['name'] }) mapping.visitModel(nameObjectInput, (x: any) => x, { visitedObjects: null, parentName: 'parent', ignore: ['age'], copy: ['height'], include: ['name'] })