Skip to content

Improve parser error on mapped type with additional property declarations #45089

Closed
@AgainPsychoX

Description

@AgainPsychoX

Suggestion

Properties generators [Ed: Mapped types] require separate type definition. Is this really a requirement by design limitations? It's weird for me that I must to merge two types to get type I actually want. Also, depending on where the [foo in Foos]: Bar part is placed, it gives two different, but both hard to understand error - it would be nice to have easy to understand error at least, even if separate type is required.

🔍 Search Terms

Properties generation. Mapped types.

✅ Viability Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

⭐ Suggestion

Make properties generator thing work if it's amongst other properties. There should be check that generated property names are other than properties defined alongside.

If not possible (due to design limitations or something), make it return easy to understand error.

📃 Motivating Example

The 17th line } & { seems just a burden.

export type PricingSpans = {
    /// Pricing for day/hour if up to `days` days.
    [days: number]: number;

    /// Pricing for day/hour if more days than specified
    above: number;
}

export const PlaceTypes = ['openSky', 'roofed', 'garage'] as const;
export type PlaceType = (typeof PlaceTypes)[number];

type PricingInfo = {
	/// Pricing spans for various place types
    [placeType in PlaceType]: PricingSpans;

    // Removing next line makes it fail, weird...
} & {

    /// Pricing model
	model: 'hour' | 'day';
}

//------------------------------------------------------

const foo: PricingInfo = {
	openSky: {
		0: 40,
		above: 30
	},
	roofed: {
		0: 50,
		above: 40
	},
	garage: {
		0: 80,
		above: 70
	},
	model: 'day',
}
Output
export const PlaceTypes = ['openSky', 'roofed', 'garage'];
//------------------------------------------------------
const foo = {
    openSky: {
        0: 40,
        above: 30
    },
    roofed: {
        0: 50,
        above: 40
    },
    garage: {
        0: 80,
        above: 70
    },
    model: 'day',
};
Compiler Options
{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "alwaysStrict": true,
    "esModuleInterop": true,
    "declaration": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "target": "ES2017",
    "jsx": "react",
    "module": "ESNext",
    "moduleResolution": "node"
  }
}

Playground Link: Provided

Other examples:

  • Weird errors generated if the property generator part is placed after any other properties: Playground Link
  • Other weird error generated if the property generator part is placed first (before any other properties): Playground Link

💻 Use Cases

Its not important issue. Its just quality of life, something rarely used could look a bit better. Workaround is just separate the property generator and join with others. What's nice about the workaround is that it report error if properties generated overlap with properties defined attached (i.e, you can add 'model' into PlaceTypes, and there is proper error).

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions