-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use return type as an inference location #11152
Comments
Does this effectively mean curried function will be inferred? const curry = <K, T>(k: K) => (t: T) => {}
curry(123)('123') // K inferred to number, T inferred to string |
That would be amazing to see. I stumbled upon a similar issue tonight, which is roughly the same as #1212. What is the progress on this? |
Another case where this would be useful: function id<T>(x: T): T { return x; }
function f(b: boolean): { n: number } {
if (b) {
return { n: 1 };
} else {
return id({ n: 1 });
}
} Find-all-references on the declaration of |
Still have this problem, and also see this: let a = [[1, 2], [3, 4]];
let b: [number, number][] = a.map(v => v);
let c: [number, number][] = a.map(v => [1,2]); Both
[1,2] is treated as number[] rather than [number, number] |
I'm moving the example from #21275 to here as I filed a duplicate type Path<T, V> = Array<string>
function path<T, A extends keyof T>(key: A): Path<T, T[A]>
function path<T>(path: string|Array<string>): Path<T, any> {
if (typeof path === 'string') return [path] as Path<T, any>
else return path as Path<T, any>
}
function field<T, V>(path: Path<T, V>) {
return {path}
}
type User = {name: string}
// Errors
field<User, string>(path('name'))
// Works
field<User, string>(path<User, 'name'>('name')) Can I do anything to help get this feature going? |
Keywords: map on array of tuple contextual contextually typed return type of lambda arrow function expressions |
I think the only reason this doesn't work is because we widen the return type of the function expression? |
Actually, I think #25937 maybe fixes (some of) this. Although undoubtedly @RyanCavanaugh is probably right - most of the remarks here are caused by the return type widening. |
Another example, simplified from #26621: type Box<T> = { value: T };
declare function box<T>(value: T): Box<T>;
type WinCondition =
| { type: 'win', player: string }
| { type: 'draw' };
let zz: Box<WinCondition> = box({ type: 'draw' }); // Error
type WinType = 'win' | 'draw';
let yy: Box<WinType> = box('draw'); // Error Would be nice if we could do better here. |
Seems like my proposal at #26979 could be a fix for this. While I don't propose the exact mechanism for literal type inference, I suggest an expression for type assertion that would prevent the type from widening. For example @k8w's code could be written this way: const a = [[1, 2], [3, 4]] as const;
const b: Array<[number, number]> = a.map(v => v);
const c: Array<[number, number]> = a.map(v => [1,2] as const); While I agree that implementing the interference mechanism is important, this could provide a quick fix. |
Would definitely like to see this done. We've hit this over in Pulumi as part of #11312. It seems really unfortunate that something as simple as: |
Looks like I hit this on DefinitelyTyped/DefinitelyTyped#30057 (comment) |
I had a PR up that made return widening contextual, rather than always - didn't really get a great chance to review and iterate it before it got out of sync though. #20976 for reference. |
Fixed in #29478. |
Thanks much @ahejlsberg ! This will be very helpful in many of our complex, highly generic code spots! |
I must be missing something. I installed Typescript 3.4.1, and still get the wrong inferrence. interface Ent { id: number, name: string };
const entities: Ent[] = [{ id: 1, name: 'one' }, { id: 2, name: 'two' }];
// Wrong type inferred: (number | string)[][]
const wrongInferredType = entities.map(ent => [ent.id, ent.name]);
// This works: [number, string][] (as it should be)
const idEntities = entities.map(ent => [ent.id, ent.name]) as [number, string][]; |
@jeremychone nothing changed w.r.t where we infer tuple types (excepting |
@weswigham Thank you. In fact, just realized I did not understand the root of the problem (which was that without typing, returning an array could not be assumed to be a tuple). |
From #11054
Today this is an error without casting
"folder"
to the literal type. We have a contextual type coming froma
that is not being used.The text was updated successfully, but these errors were encountered: