Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@doubleedesign
Last active February 5, 2023 11:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doubleedesign/2773d9f9aabfdac6171b7f347115e945 to your computer and use it in GitHub Desktop.
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
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'])
);
});
});
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