Skip to content

Commit

Permalink
[objasinterface] Make sure that keys/values/entries are typed to work…
Browse files Browse the repository at this point in the history
… against class instances too (#329)

## Summary:
Noticed in webapp that some uses are passing a class instance and we should support that. Flow error indicated using an interface rather than object type so that it would match both objects and class instances. So this does that.

Issue: XXX-XXXX

## Test plan:
`yarn flow`

Author: somewhatabstract

Reviewers: kevinbarabash, benchristel

Required Reviewers:

Approved By: kevinbarabash

Checks: ✅ codecov/project, ✅ Test (macOS-latest, 16.x), ✅ CodeQL, ✅ Lint, flow, and coverage check (ubuntu-latest, 16.x), ⏭  dependabot, ✅ Analyze (javascript), ✅ Prime node_modules cache for primary configuration (ubuntu-latest, 16.x), ✅ gerald

Pull Request URL: #329
  • Loading branch information
somewhatabstract authored Jul 14, 2022
1 parent 3b79965 commit 753b193
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/nice-shirts-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@khanacademy/wonder-stuff-core": patch
---

Broaden typing for keys/values/entries methods
12 changes: 12 additions & 0 deletions packages/wonder-stuff-core/src/__tests__/entries.flowtest.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,15 @@ import {entries} from "../entries.js";
// $FlowExpectedError[incompatible-type]
const [___, ____]: [string, number] = entries1[0];
}

{
// should work with class instances
class Foo {
a: string;
b: string;
}
const foo = new Foo();

// This should not be erroring.
const _ = entries(foo);
}
12 changes: 12 additions & 0 deletions packages/wonder-stuff-core/src/__tests__/keys.flowtest.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,15 @@ import {keys} from "../keys.js";
// This should not be erroring.
const _ = keys(obj3);
}

{
// should work with class instances
class Foo {
a: string;
b: string;
}
const foo = new Foo();

// This should not be erroring.
const _ = keys(foo);
}
12 changes: 12 additions & 0 deletions packages/wonder-stuff-core/src/__tests__/values.flowtest.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,15 @@ import {values} from "../values.js";
// $FlowExpectedError[incompatible-call]
const __ = values<number>(obj2);
}

{
// should work with class instances
class Foo {
a: string;
b: string;
}
const foo = new Foo();

// This should not be erroring.
const _ = values(foo);
}
6 changes: 4 additions & 2 deletions packages/wonder-stuff-core/src/entries.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
/**
* Return an array of key/value tuples for an object.
*
* @param {$ReadOnly<{[K]: V}>} obj The object for which the values are
* @param {$ReadOnly<interface {[K]: V}>} obj The object for which the values are
* to be returned.
* @returns {Array<[K, V]>} An array of key/value tuples for the object.
*/
export function entries<K, V>(obj: $ReadOnly<{[K]: V}>): Array<[K, V]> {
export function entries<K, V>(
obj: $ReadOnly<interface {[K]: V}>,
): Array<[K, V]> {
// This cast is deliberate as Object.entries is typed to return
// Array<[string, mixed]>, but we want to return Array<[K, V]>.
// $FlowIgnore[unclear-type]
Expand Down
6 changes: 4 additions & 2 deletions packages/wonder-stuff-core/src/keys.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
/**
* Return an array of the enumerable keys of an object.
*
* @param {$ReadOnly<{[string]: mixed}>} obj The object for which the values are
* @param {$ReadOnly<interface {[string]: mixed}>} obj The object for which the values are
* to be returned.
* @returns {Array<$Keys<O>>} An array of the enumerable keys of an object.
*/
export function keys<O: {[string]: mixed}>(obj: $ReadOnly<O>): Array<$Keys<O>> {
export function keys<O: interface {[string]: mixed}>(
obj: $ReadOnly<O>,
): Array<$Keys<O>> {
return Object.keys(obj);
}
4 changes: 2 additions & 2 deletions packages/wonder-stuff-core/src/values.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
/**
* Return an array of the enumerable property values of an object.
*
* @param {$ReadOnly<{[mixed]: V}>} obj The object for which the values are
* @param {$ReadOnly<interface {[mixed]: V}>} obj The object for which the values are
* to be returned.
* @returns {Array<V>} An array of the enumerable property values of the object.
*/
export function values<V>(obj: $ReadOnly<{|[mixed]: V|}>): Array<V> {
export function values<V>(obj: $ReadOnly<interface {[mixed]: V}>): Array<V> {
// This is a deliberate cast through any.
// Object.values returns Array<mixed> and we want to return Array<V>.
// $FlowIgnore[unclear-type]
Expand Down

0 comments on commit 753b193

Please sign in to comment.