Last active
February 5, 2023 11:30
-
-
Save doubleedesign/2773d9f9aabfdac6171b7f347115e945 to your computer and use it in GitHub Desktop.
Function to determine the TypeScript type of a given value using a predefined list of types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import savedArtists from '../json-data/test/artists.json' assert { type: 'json'}; | |
import { getType } from './typechecker'; | |
// NOTE: These tests are a work in progress, | |
as I have so far only completed work with the "Artist" type on the project at the time of writing | |
describe('Typechecker', () => { | |
it('Correctly identifies and Artist', () => { | |
const item = savedArtists[0]; | |
const type = getType(item); | |
expect(type).toEqual(['Artist']); | |
}); | |
it('Correctly identifies that an Artist is not an Album', () => { | |
const item = savedArtists[0]; | |
const type = getType(item); | |
expect(type).toEqual( | |
expect.not.arrayContaining(['Album']) | |
); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { resolve } from 'path'; | |
import * as TJS from 'typescript-json-schema'; | |
/** | |
* Determine the TypeScript type of a given value | |
* using a predefined list of types | |
* @param item - The value to check | |
* @returns string[] - Array of types specified in the function that the item satisfies | |
*/ | |
export function getType(item: unknown): string[] { | |
// If the given item is not an object, bail early and return its basic type | |
if(typeof item !== 'object') { | |
return [typeof item]; | |
} | |
const typesToCheck = ['Artist', 'Album', 'Track']; | |
const itemProperties = Object.keys(item); | |
const matches = []; // Return an array in case the given item satisfies more than one of the given types | |
const program = TJS.getProgramFromFiles( | |
[resolve('./api/types.ts')] // File containing the type definitions for the typesToCheck listed above | |
); | |
// Generate JSON schema object for each given type | |
// required: true is, well, required, so we can check the given item's keys against the required properties of the type i.e. the ones we 100% expect to be present | |
[...typesToCheck].forEach((type) => { | |
const schema = TJS.generateSchema(program, type, { required: true }); | |
if(schema.required.every(v => itemProperties.includes(v))) { | |
matches.push(type); | |
} | |
}); | |
if(matches.length > 1) { | |
console.warn('Type check returned more than one match. This may lead to unexpected results.'); | |
} | |
return matches; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment