I'm working on creating a sample of a generic class in TypeScript. My goal is to have a generic class named RecordsProcessor
that is limited to only accept types that are arrays of objects.
If I try to pass a number to the constructor, TypeScript correctly rejects it.
However, if I pass an array of numbers, TypeScript mistakenly allows it.
Is there a way to ensure that this generic class is restricted to only accepting types that are arrays of objects with properties to display?
// RECORDS (general)
interface IRecord { }
interface IRecords extends Array<IRecord> { }
// PERSONS (specific)
interface IPerson {
firstName: string,
lastName: string,
age: number
}
interface IPersons extends Array<IPerson> { }
// FLASHCARDS (specific)
interface IFlashcard {
front: string,
back: string
}
interface IFlashcards extends Array<IFlashcard> { }
class RecordsProcessor<T extends IRecords> {
records: T;
constructor(records: T) {
this.records = records;
}
generateCommaSeparatedValueString(): string {
let r: string = '';
this.records.forEach((record) => {
let count = 1;
for (const key in record) {
r += `${record[key]}`;
if (count === Object.keys(record).length) {
r += '\n';
} else {
r += ', ';
}
count += 1;
}
});
return r;
}
}
const employees: IPersons = [
{
firstName: 'David',
lastName: 'Krustchen',
age: 34
},
{
firstName: 'Melitta',
lastName: 'Schönbrecher',
age: 24
}
]
const employeeProcessor = new RecordsProcessor<IPersons>(employees);
console.log(employeeProcessor.generateCommaSeparatedValueString());
const flashcards: IFlashcards = [
{
front: 'lamp',
back: 'die Lampe'
},
{
front: 'table',
back: 'der Tisch'
},
{
front: 'computer',
back: 'der Computer'
},
{
front: 'book',
back: 'das Book'
}
]
const flashcardProcessor = new RecordsProcessor<IFlashcards>(flashcards);
console.log(flashcardProcessor.generateCommaSeparatedValueString());
// yields error: number does not satisfy the contraint 'IRecords'
// const numberProcessor = new RecordsProcessor<number>(23);
const numbers: number[] = [1, 5, 3, 6, 7];
const arrayOfNumbersProcessor = new RecordsProcessor<number[]>(numbers); // this should also be forbidden by TypeScript
console.log(arrayOfNumbersProcessor.generateCommaSeparatedValueString());