Repository: TypeScript
Issue: Correctly handle generic functions (e.g.: `Object.freeze`) passed as callbacks to generic functions (e.g.: `Array.prototype.map`)
Labels: Suggestion,In Discussion,Has Repro

# Suggestion

<!--
  Please fill in each section completely. Thank you!
-->

## 🔍 Search Terms

<!--
  💡 Did you know? TypeScript has over 2,000 open suggestions!
  🔎 Please search thoroughly before logging new feature requests as most common ideas already have a proposal in progress.
  The "Common Feature Requests" section of the FAQ lists many popular requests: https://github.com/Microsoft/TypeScript/wiki/FAQ#common-feature-requests

  Replace the text below:
-->

- array map generic callback
- object.freeze array map

## ✅ Viability Checklist

<!--
   Suggestions that don't meet all these criteria are very, very unlikely to be accepted.
   We always recommend reviewing the TypeScript design goals before investing time writing
   a proposal for ideas outside the scope of the project.
-->
My suggestion meets these guidelines:

* [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
* [x] This wouldn't change the runtime behavior of existing JavaScript code
* [x] This could be implemented without emitting different JS based on the types of the expressions
* [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
* [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).


## ⭐ Suggestion

A generic transforming function (e.g.: `Object.freeze`) passed as a callback to a generic mapping function (such as `Array.prototype.map`), should be handled similarly to an arrow function with inferred types.

## 📃 Motivating Example

From [engine262/src/engine.mjs](https://github.com/engine262/engine262/blob/d619a566d6508c8e33258be61d3934bc5f49f623/src/engine.mjs#L23-L54):

```ts repro
// @target: ES2015
// @filename: index.ts
export const FEATURES = Object.freeze([
//                 ^?
	{
		name: 'Top-Level Await',
		flag: 'top-level-await',
		url: 'https://github.com/tc39/proposal-top-level-await',
	},
	{
		name: 'Hashbang Grammar',
		flag: 'hashbang',
		url: 'https://github.com/tc39/proposal-hashbang',
	},
	{
		name: 'RegExp Match Indices',
		flag: 'regexp-match-indices',
		url: 'https://github.com/tc39/proposal-regexp-match-indices',
	},
	{
		name: 'FinalizationRegistry.prototype.cleanupSome',
		flag: 'cleanup-some',
		url: 'https://github.com/tc39/proposal-cleanup-some',
	},
	{
		name: 'Arbitrary Module Namespace Names',
		flag: 'arbitrary-module-namespace-names',
		url: 'https://github.com/tc39/ecma262/pull/2154',
	},
	{
		name: 'At Method',
		flag: 'at-method',
		url: 'https://github.com/tc39/proposal-item-method',
	},
].map(Object.freeze));
```

[Workbench Repro](https://www.typescriptlang.org/dev/bug-workbench/?target=2&lib=&ts=#code/PTAEAEBcEMCcHMCmkBcoCiBlATABgIwCsAUCBAGYCWANogHbQC2ialdAJogB4B0kAzsW4AHAPaxIoAMai6-SQDF0AQQAqAVQBKWUAF5QAeQBGAK0RTIPcrESIAXogAUAbVJhQHz1++gAegH5iAEgAb2CghmY0AHJVUWEAWgAZRAA3RGpQZQB3aEpIaIAacPJqaHgYyHiE2nTqBOhc-KLwgFdYahiAC0hIYX4UEHh8rtajHhlGYEgpAGYATmBhWHjRfmh6qsTajIamguKggF9DsKCIphZQaIAJaH4uo2g6eFAAcVgmRjgW89Ly7r3R7PeC-ILtTrXHp9AZDEZjCaiKYzBZLFZidb1LpAp4vX4nYJnC5Ra6aRDwdBcYSgACy0BmXVAAEkOJQpIh+GD-hVrjYkFSEt8GQk2Ow2RywRDur1+oNgMNIKNxpNpnNFstVpiEnyRIL6VIuiLWezOYcCaFwpErtEFGwNpQ7PTKLIycN5LAAJ48DVVSAe4SICa0Z6tYSYJGILllHnRKTBuihhL8COSjrSmFyhVKxHItVozUbBJxxAhxLJ5j406Wy4xZSwIz5T6e2miditWigAByl34wmg7K7PajAOucAbkCbHsFrfbiASVt7-bnC9TkOi0NlcMVCJVKMW5m+2AAbNglu3qMBsEQACyVwnVknRZSSGnILqt4cx+mCt8fw7gtMoRlWF5XhZUkVVVENQxQt8kQRgf0VP9ggJABdHhvmERxjDMCwrBsexEAASiIgBuYggA)

### Expected type:
```ts
export const FEATURES: readonly {
	readonly name: string;
	readonly flag: string;
	readonly url: string;
}[];
```

<details>
<summary>Like when using an arrow function:</summary>

```ts repro
// @target: ES2015
// @filename: index.ts
export const ARROW_FEATURES = Object.freeze([
//                       ^?
	{
		name: 'Top-Level Await',
		flag: 'top-level-await',
		url: 'https://github.com/tc39/proposal-top-level-await',
	},
	{
		name: 'Hashbang Grammar',
		flag: 'hashbang',
		url: 'https://github.com/tc39/proposal-hashbang',
	},
	{
		name: 'RegExp Match Indices',
		flag: 'regexp-match-indices',
		url: 'https://github.com/tc39/proposal-regexp-match-indices',
	},
	{
		name: 'FinalizationRegistry.prototype.cleanupSome',
		flag: 'cleanup-some',
		url: 'https://github.com/tc39/proposal-cleanup-some',
	},
	{
		name: 'Arbitrary Module Namespace Names',
		flag: 'arbitrary-module-namespace-names',
		url: 'https://github.com/tc39/ecma262/pull/2154',
	},
	{
		name: 'At Method',
		flag: 'at-method',
		url: 'https://github.com/tc39/proposal-item-method',
	},
].map((feature) => Object.freeze(feature)));
```

[Workbench Repro](https://www.typescriptlang.org/dev/bug-workbench/?target=2&lib=#code/PTAEAEBcEMCcHMCmkBcoCiBlATABgIwCsAUCBAGYCWANogHbQC2ialdAJogB4B0kAzsW4AHAPaxIoAMai6-SQEEASkoDyAdQD6AMXQKAKgFUlWUAF5QqgEYArRFMg9ysRIgBeiABQBtUmFABgUHBIaAAegD8xACQAN4x0QzMaADk+qLCALQAMogAbojUoAoA7tCUkCkANAnk1NDwqZAZmbQF1JnQZRXVCQCusNSpABaQkML8KCDwFcN9VjwyjMCQUgDMAJzAwrAZovzQHc1ZbYWd3ZU10QC+V-HRiUwsoCkAEtD8w1bQdPCgAOKwJiMOC9B51BojD5fH7wMHRAZDF6jcaTaazeaLUTLVabba7MQHDrDaHfX5g24xe6PZIvJSIeDoLjCUAAWWgq2GoAAkhxKFJEPx4RDGi8XEhmZkQZzMmx2PzBfDESMxhMpsAZpA5gslit1lsdnsiZlxSIpRypMNZXyBUKrpS4gkks8Uto2IdKG4OZRZPSZvJYABPHiG5qQQPCRCLWg-PrCTDYxDC+qilJSGN0OOZfiJpWDFWo9Wa7VYnH6-FGw6ZdOIWNZHPMCl3J1PVIKWBWCpAoNs0TsPq0UAAOSe-GE0AFw9HychLzgncg3cDUr7A8QmWdY4n683eaRKRRavRWsxutxW3sIOwADZsNsB9RgNgiAAWJtUlu0lIKSSs5DDPsZ1TDkpX-QCrgRfNkVVNENQxHVsT1PFDUJKsKkQRhQK1cCYkpABdHgQWETxPHIWtIAGRAAEpzAAPksWx7EcZxXA8UjyMoqiuIAbmIIA)</details>

### Actual type:
```ts
export const FEATURES: readonly Readonly<unknown>[];
```

## 💻 Use Cases

Getting correct type inference for **JavaScript** code on the wild web.

## Related issues
- <https://github.com/microsoft/TypeScript/issues/10725>