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.

Using the "in" operator should make bracket access safe on an object

See original GitHub issue

Search Terms

object in keyof bracket operator in

Suggestion

Checking a key with the “in” operator on an object should make it safe to to use in brackets

Use Cases

Useful when writing functions that process input JSON/doesn’t have a concrete type.

Examples

//  Ideally this uses TypeScripts control flow logic to allow the bracket access.
function getPropFailsToCompile(data: object, key: string): any {
    if (!(key in data)) {
        throw new Error("Data is malformed")
    }
    return data[key]
}

// Compiles but keyof object has type 'never' in Typescript
function getPropCompilesButNotReasonable(data: object, key: keyof object): any {
    if (!(key in data)) {
        throw new Error("Data is malformed")
    }
    return data[key]
}

// Best way I've gotten this to work.
function getPropWorks(data: object, key: string): any {
    if (!(key in data)) {
        throw new Error("Data is malformed")
    }
    return (<any>data)[key]
}

Checklist

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, etc.)
  • [ x] This feature would agree with the rest of TypeScript’s Design Goals.

Issue Analytics

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

github_iconTop GitHub Comments

3reactions
nightpoolcommented, Jan 27, 2021

I had the same issue today (Playground Link)

I was able to get around it by defining an existsIn helper as follows:

function existsIn<T>(obj: T, name: string | number | symbol): name is keyof T {
  return name in obj;
}

And then I was able to define the function I wanted

const values = {test: 'this value', foo: 'that value'};

const handleMessage = (name: string): void => {
  if (existsIn(values, name)) { // instead of `name in values`
    console.log(values[name]);
  }
}

maybe there’s some unsoundness I haven’t considered here, but it seems like it should be pretty simple to have name in obj imply the same name is keyof T assertion that an explicit type guard does!

0reactions
stuft2commented, Nov 18, 2021

@RyanCavanaugh What is the typescript recommended way to determine that an unknown variable is an object with a given property on it?

@nightpool’s suggestion is fairly good but like he said, “it should be pretty simple to have name in obj imply the type correctly”. I’m always typing something like the following example even thought it doesn’t work and I intuitively think it should:

const obj: unknown = { foo: 'bar'}
if (typeof obj === 'object' && obj !== null && Object.hasOwnProperty.call(obj, 'foo') && typeof obj.foo === 'string') {
  //                                                                                             ^^^^^ ERROR
}

A common use case is when catching an error. The error must either be typed as unknown or any but it’s a hassle to type check an error that has additional properties on it. For example, node errors usually have a code property on it that can’t be type checked without the ritual.

There needs to be a documented, typescript-recommended way of accomplishing this.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Safe navigation operator with bracket property accesor
I would like to know if there is there a way to access the property using the dot notation, or if there is...
Read more >
Optional chaining (?.) - JavaScript - MDN Web Docs - Mozilla
Optional chaining with expressions​​ This is particularly useful for arrays, since array indices must be accessed with brackets.
Read more >
Member access operators and expressions - Microsoft Learn
You use several operators and expressions to access a type member. These operators include member access ( . ), array element or indexer ......
Read more >
The Safe Navigation Operator (&.) in Ruby - Georgi Mitrev
The syntax is a bit awkward but I guess we will have to deal with it because it does make the code more...
Read more >
SQL Statements, To Square Bracket Or Not? | DEVelopers HUT
Most commonly, we see the need to use square brackets when people use space when naming objects and fields. Examining the original example ......
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