Reputation: 86
I'm trying to figure out how to correctly type the parameter applySnapshotFn
which is a function that will always take the arguments snapshot
and spread ...args
.
const applyCssSnapshotFn = (snapshot, cssFileName) => {};
const applyJsSnapshotFn = (snapshot, jsFileName, currentVersion) => {};
const upgradeSnapshot = (
snapshots: SnapshotType,
applySnapshotFn: () => void, // How do I properly type this to accept ({snapshot, ...args})?
args: Record<string, string | boolean>
) => {
snapshots.map(({ snapshot }) => {
if (snapshot) {
applySnapshotFn({ snapshot, ...args });
}
});
};
// Calling the function
upgradeSnapshot(snapshots, applyCssSnapshotFn, {
cssFileName,
});
upgradeSnapshot(snapshots, applyJsSnapshotFn, {
jsFileName,
currentVersion,
});
TypeScript playground link for better example
Upvotes: 1
Views: 64
Reputation: 3672
I've updated your code on the playground to propose you a solution
type Snapshot = Record<string, string>;
type SnapshotType = {
version: string;
snapshot: Snapshot[];
}
interface UpgradeCssSnapshotArgs {
cssFileName: string;
};
interface UpgradeJsSnapshotArgs {
jsFileName: string;
currentVersion: string;
};
type SnapshoFnType<T extends UpgradeCssSnapshotArgs | UpgradeJsSnapshotArgs> = (params: { snapshot: Snapshot[]; } & T) => void;
const snapshots: SnapshotType[] = [{
version: '0.2',
snapshot: [
{
description: 'Description of action',
action: 'actions to perform'
}
]
}];
const applyCssSnapshotFn = (params: { snapshot: Snapshot[] } & UpgradeCssSnapshotArgs) => {
console.log(params);
};
const applyJsSnapshotFn = (params: { snapshot: Snapshot[] } & UpgradeJsSnapshotArgs) => {
console.log(params);
};
const upgradeSnapshot = <T extends UpgradeCssSnapshotArgs | UpgradeJsSnapshotArgs, >(
snapshots: SnapshotType[],
applySnapshotFn: SnapshoFnType<T>,
args: T
) => {
snapshots.map(({ snapshot }) => {
if (snapshot) {
const params = { snapshot, ...args };
applySnapshotFn(params);
}
});
};
// Calling the function
upgradeSnapshot(snapshots, applyCssSnapshotFn, {
cssFileName: 'Theme.css'
});
upgradeSnapshot(snapshots, applyJsSnapshotFn, {
jsFileName: 'Home.js',
currentVersion: '0.1',
});
Upvotes: 1