I'm looking to use generics to enforce that the type of val1 should match the type of val2 for each element in an array.
interface SameTypeContainer<T> {
val1: T,
val2: T;
}
test([
{
val1: 'string',
val2: 'also string'
},
{
val1: 5,
val2: false // expect to throw error since type is not number
}
]);
function test(_: SameTypeContainer<any>[]) { }
This does not cause an error. I expect this to raise a typescript error for the following reason:
In the second element of the array passed to the test function, val1 is a number and val2 is a string. The SameTypeContainer interface is supposed to enforce that the type of val1 matches the type of val2.
Next I tried to redefine the test function to use generics:
function test<T>(_: SameTypeContainer<T>[]) { }
Now I receive an error, but for the wrong reason. The compiler expects val1 to be of type string and val2 to be of type string, because that is how the first element in the array was defined.
I want each element in the array to be evaluated whether it satisfies the given generics independently.
Any help would be appreciated!
UPDATE:
Thanks for your help! I appreciate it! I'm starting to understand using extends, but having trouble expanding it to my actual use case:
export type Selector<S, Result> = (state: S) => Result;
export interface SelectorWithValue<S, Result> {
selector: Selector<S, Result>;
value: Result;
}
export interface Config<T, S, Result> {
initialState?: T;
selectorsWithValue?: SelectorWithValue<S, Result>[];
}
export function createStore<T = any, S = any, Result = any>(
config: Config<T, S, Result> = {}
): Store<T, S, Result> {
return new Store(config.initialState, config.selectorsWithValue);
}
export class Store<T, S, Result> {
constructor(
public initialState?: T,
public selectorsWithValue?: SelectorWithValue<S, Result>[]
) {}
}
const selectBooleanFromString: Selector<string, boolean> = (str) => str === 'true';
const selectNumberFromBoolean: Selector<boolean, number> = (bool) => bool ? 1 : 0;
createStore({
selectorsWithValue: [
{ selector: selectBooleanFromString, value: false },
{ selector: selectNumberFromBoolean, value: 'string' } // should error since isn't a number
],
});
Desired: for each element in the array passed to the createStore function, the second type of the selector should match the type of the value.
Ex: if the selector property is of type Selector<boolean, number>, the value property should be of type number, independent of what the other elements of the array's types.
Here's my first attempt modifying the Typescript playground @jcalz provided for the above nested use case: