Let's say I've got an object like this:
class MyObject {
requiredString: string,
nullableString: string | undefined
}
and I want to be able to deserialize JSON into this object while enforcing that it has the required string, but not enforcing that it has the nullable one.
So, all these tests should pass:
const validJson1 = '{"requiredString":"a needed value!","nullableString":"an unneeded value!"}'
const validJson2 = '{"requiredString":"whatever!"}'
const invalidJson = '{"nullableString":"I am the God Of Teeth!"}'
class MyObject {
requiredString: string,
nullableString: string | undefined
}
function myMagicValidator<T>( objectInstance:T ) {
// Throws exception if objectInstance is not a valid <T>
}
test('works whatsoever', () => {
let testObject = JSON.parse(validJson1)
myMagicValidator<MyObject>(testObject)
})
test('respects optional values', () => {
let testObject = JSON.parse(validJson2)
myMagicValidator<MyObject>(testObject)
})
test('enforces required values', () => {
let testObject = JSON.parse(invalidJson)
expect(myMagicValidator<MyObject>(testObject)).toThrow()
})
// Ideally this could work too, but it's not strictly needed
const invalidJson2 = '{"requiredString":5,"nullableString":"another value!"}'
test('enforces type safety', () => {
let testObject = JSON.parse(invalidJson2)
expect(myMagicValidator<MyObject>(testObject)).toThrow()
})
But the trick is that I don't own the object, MyObject actually gets imported from another package and isn't modifiable in my code. The requirement is that if another field is added to MyObject that's required, myMagicValidator should automatically start checking for it when node_modules updates to include the new field.