Skip to content

Instantly share code, notes, and snippets.

@Landerson352
Created August 10, 2022 22:18
Show Gist options
  • Save Landerson352/57f416296e7b0aefed4883383bc5fcec to your computer and use it in GitHub Desktop.
Save Landerson352/57f416296e7b0aefed4883383bc5fcec to your computer and use it in GitHub Desktop.
A React component model that accepts various shapes of data by specifying the object properties to expect in the collection.
import React from 'react';
type BaseObject<ColorKey extends string, PercentKey extends string> = {
[key in ColorKey]: string;
} &
{
[key in PercentKey]: number;
};
function GenericListView<
ColorKey extends string,
PercentKey extends string
>(props: {
colorKey: keyof BaseObject<ColorKey, PercentKey>;
percentKey: keyof BaseObject<ColorKey, PercentKey>;
values: BaseObject<ColorKey, PercentKey>[];
}): React.ReactElement {
const { colorKey, percentKey, values } = props;
return (
<React.Fragment>
{values.map((value, i) => (
<div key={i}>
{value[colorKey]}: {value[percentKey]}%
</div>
))}
</React.Fragment>
);
}
// Example "House" type and wrapper for GenericListView
type House = {
paint: string;
apr: number;
};
const HouseListView: React.FC<{ values: House[] }> = (props) => (
<GenericListView<'paint', 'apr'>
colorKey="paint"
percentKey="apr"
{...props}
/>
);
// Example "Dog" type and wrapper for GenericListView
type Dog = {
fur: string;
age: number;
};
const DogListView: React.FC<{ values: Dog[] }> = (props) => (
<GenericListView<'fur', 'age'> colorKey="fur" percentKey="age" {...props} />
);
const TsTests: React.FC = () => {
return (
<React.Fragment>
{/* Inline example */}
<GenericListView<'color', 'percent'>
colorKey="color"
percentKey="percent"
values={[{ color: 'purple', percent: 3 }]}
/>
{/* Prepared wrapper examples */}
<HouseListView values={[{ paint: 'blue', apr: 5 }]} />
<DogListView values={[{ fur: 'red', age: 2 }]} />
</React.Fragment>
);
};
export default TsTests;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment