question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Union in a computed property allows any assignment to property value

See original GitHub issue

TypeScript Version: 4.0.0-dev.20200518

Search Terms: computed property, union

Code

type Key = 'a' | 'b';

const index1: Record<Key, string> = { a: '', b: 0 }; // Errors as expected, ok
const index2: Record<Key, string> = { a: '', b: '' };

const b: Key = 'b';

const index3: Record<Key, string> = { ...index2, [b]: 0 }; // Errors as expected, ok

declare var k: Key;

// No errors, allowing anything to be assigned to string
const index4: Record<Key, string> = { ...index2, [k]: [] };
const index5: Record<Key, string> = { a: '', b: '', [k]: 0 };

Expected behavior: Expected error for invalid assignments in index4 and index5.

Actual behavior: No error, allowing anything to be assigned to string

Playground Link: here

Related Issues: https://github.com/microsoft/TypeScript/issues/36920: perhaps the computed property is deemed an excess property, though I don’t think it should be

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:8
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
nth-commitcommented, Oct 18, 2020

Here’s my minimal example, similar to OP’s:

type Key = 'foo' | 'bar';

// Ex 1. Attempting to assign `unknown` in place of `string`

declare const unknownValue: unknown;

const dict1: Partial<Record<Key, string>> = {
  foo: unknownValue, // Error ✔️
};

// Ex 2. Attempting to assign `unknown` in place of `string`, except this time using a computed property

declare const keyValuePair: {
  key: Key;
  value: unknown;
};

const dict2: Partial<Record<Key, string>> = {
  [keyValuePair.key]: keyValuePair.value, // No Error ❌
};
1reaction
weswighamcommented, Jun 29, 2020

So, there’s two things, first:

declare var str: string;

const x = { a: "", b: "" };

const y = { [str]: 0, ...x };

const z = { ...x, [str]: 0 };

A computed property name with a non-literal name produces an index signature. getSpreadType in the compiler elides the index signature from the output type if either input elides the index signature. So you’ll note in the above, no type has an index signature - the types introduced by the computed names simply evaporate. Now… including it is a little awkward, as it can easily produce a type like

{
    [x: string]: number;
    a: string;
    b: string;
}

where the index signature does not actually cover all the members in the type, but that can be fixed.

Second, Record<Key, string> is {a: string, b: string} - when {[x: string]: whatever, a: string, b: string} is assigned to it, the index signature is not considered to be an excess property. This is done for good reason! If the computed name only actually edits the known names, then there aren’t any excess properties (and index signatures being as wishy-washy as they are, that’s how we prefer it). Since the index signature can’t be excess, the desired error must come from property assignability - which, when you look at it, you realize something’s missing - the issue is that the computed property doesn’t edit the types of the properties it may overwrite!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is there a way to declare a union type in TypeScript with ...
Is there a way to declare a union type in TypeScript with computed strings based on existing constants? · The Task: · What...
Read more >
Computed Properties - Vue.js
Think of a computed property as declaratively describing how to derive a value based on other values - its only responsibility should be...
Read more >
NJ Guide to Affordable Housing 2022 UNION COUNTY - NJ.gov
NJ Guide to Affordable Housing 2022. UNION COUNTY o source development / aka street type tenure units area phone agent agent address area_2...
Read more >
SECTION 1: EVALUATING BORROWER INCOME CHAPTER 4
eligible for a loan; (2) calculate the applicant's ability to repay a loan; and (3) determine the ... law for property taxes paid...
Read more >
Part 31 - Contract Cost Principles and Procedures
Actual cash value means the cost of replacing damaged property with other property of ... and that assigns the cost of such benefits...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found