6

So I am working on a react-native project. I was hoping if one could infer Generic types from implementation.

type itemType<T> = { item: T };

const someItem = {
    item: 'Some String'
};

type someItemType = typeof someItem;
// So Here someItemType will be {item: string}, i want it to be itemType<string> and 
// in this example i have implemented itemType but in real use case i want to infer 
//it from the actual implementation  

2 Answers 2

4

Partial inference on variables is not supported at present in typescript. Your only option is to use the inference behavior of function:

type itemType<T> = { item: T };
const createItemType = <T>(o: itemType<T>) => o;

const someItem = createItemType({ //someItem is typed as itemType<string>
    item: 'Some String'
})

Just one note, it might not matter that in your original example someItem is typed as {item: string}, it will still be assignable to itemType<string> because typescript uses structural compatibility to determine assignability. So if the structure is compatible all is ok:

type itemType<T> = { item: T };

const someItem ={ 
    item: 'Some String'
}
const someOtherItem: itemType<string> = someItem // ok
Sign up to request clarification or add additional context in comments.

8 Comments

In this case, I wouldn't write extra runtime code as there is no benefit to making the names match outside of a nominal type system.
@Fenton agreed, that is why I pointed out it does not much matter what the actual type if someItem is, al least with regard to future assignability to itemType<string>. There might be benefit in ensuring the object conforms to the itemType<T> interface at declaration site, rather than on future usage, I'd expect the perf impact of the identity function used to not be too high in most scenarios.
I famously don't worry about performance impact - I worry about having to go back and change the program in six months :)
@Fenton I must admit, while I do worry about that I have used such functions to help with inference all in one line const someItem = (<T>(o: itemType<T>) => o)({ item: 'Some String' }) I will understand then in 6 months.. not sure anybody else understands them right now :)
I have some code that looks a bit like this in C#. I think if you flash it up for half a second and ask people to guess what they saw, and they answer "A Regular Expression" it's time to refactor.
|
2

It doesn't matter whether the type is defined as { item: string } or itemType<string> as TypeScript uses structural typing. That means the two are the same, because they have identical structures.

For example, you can assign values of either type to each other type:

type itemType<T> = { item: T };

const someItem = {
    item: 'Some String'
};

type someItemType = typeof someItem;

const a: itemType<string> = { item: 'exmaple a' };
const b: someItemType = { item: 'exmaple b' };

let c: itemType<string>;

c = a;
c = b;

let d: someItemType;

d = a;
d = b;

3 Comments

So the thing is i do not want to write type itemType<T> = { item: T }; i want to infer it from the implementation.
That way if i update the original object my types are automatically updated.
If you update the original object, it may no longer be an itemType<T>.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.