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: