Describing this concept can be a bit challenging, so let's jump straight into the code. Imagine I am working with strings that follow this specific format:
type ColumnName<
Prefix extends string,
Period extends 'month' | 'week'
> = `${Prefix}.${Period}`;`
For instance,
ColumnName<'dimension_date', 'month'>
would result in 'dimension_date.month'
. Moving on,
type Month<Prefix extends string> = ColumnName<Prefix, 'month'>;
type Week<Prefix extends string> = ColumnName<Prefix, 'week'>;
Now, there's a function that accepts either a Month
or a Week
, along with a Prefix
:
const get = <Prefix extends string>(
column: Month<Prefix> | Week<Prefix>,
prefix: Prefix
) => {
const monthColumn: ColumnName<Prefix, 'month'> = `${prefix}.month`;
if (column === monthColumn) {
console.log(column); // The column is of type `${Prefix}.month`, as expected
}
};
This function behaves correctly. However, my requirement is to have column
as an object property:
type MonthObject<Prefix extends string> = { [K in Month<Prefix>]: number };
type WeekObject<Prefix extends string> = { [K in Week<Prefix>]: number };
const getObj = <Prefix extends string>(
object: MonthObject<Prefix> | WeekObject<Prefix>,
prefix: Prefix
) => {
const monthColumn: ColumnName<Prefix, 'month'> = `${prefix}.month`;
if (monthColumn in object) {
console.log(object); // The object could potentially be of type MonthObject<Prefix> | WeekObject<Prefix>, but we expect it to only be of type MonthObject<Prefix>.
}
}
Is there a way for TypeScript to know within the if statement that the type should exclusively be MonthObject<Prefix>
?