function customFunction<T, NT extends Record<string, string | number | boolean>>(
data: T,
normalize?: (data: T) => NT,
) {
const normalizedData = normalize ? normalize(data) : {};
return Object.keys(normalizedData);
}
customFunction(10, (v) => v);
// Error(Type 'number' is not assignable to type 'Record<string, string | number | boolean>')
// This behavior is CORRECT
customFunction(10, (data) => ({ data }));
// No error
// This behavior is CORRECT
customFunction({ data: 10 }, (v) => v);
// No error
// This behavior is CORRECT
function adjustedFunction<T, NT extends Record<string, string | number | boolean>>(
data: T,
normalize: (data: T) => NT = (v) => v,
// ERROR: Type 'T' is not assignable to type 'NT'.
// 'NT' could be instantiated with an arbitrary type which could be unrelated to 'T'
) {
const normalizedData = normalize(data);
return Object.keys(normalizedData);
}
adjustedFunction(10);
// no error
// This behavior is INCORRECT, should throw an error
adjustedFunction(10, (data) => ({ data }));
// WORKS
// This behavior is CORRECT
adjustedFunction({ data: 10 });
// WORKS
// This behavior is CORRECT
The function customFunction
has been adapted to meet the requirement of having the normalize
parameter optional with a default value. The default value for normalize
is set to an empty object if it is not provided.
To rewrite adjustedFunction
to fit the requirements, conditional typing and default values can be used appropriately to handle different scenarios and ensure correct behavior.