-
Notifications
You must be signed in to change notification settings - Fork 185
ts options #1024
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ts options #1024
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These types look generally very good. I'm excited about being able to have a generic Data<T>
, and tsd
seems very useful.
I tried to get VSCode to give me the field-level auto complete that this should enable. I'm not sure I got it right, but this is my test file:
// setup
import {Data, Row} from "./data";
import { valueof } from "./options";
interface DatumShape extends Row {
name: string;
hairColor: "red" | "green";
height: number;
shoeSize: number;
}
const data: Data<DatumShape> = [
{name: "Bob", hairColor: "red", height: 180, shoeSize: 11.5},
{name: "Sarah", hairColor: "green", height: 170, shoeSize: 7},
] as const;
// test autocomplete
valueof(data, "eyeColor");
valueof(data, "")
I assume that the second parameter to valueof
is similar to the channel options we'd pass in a fully TS-ified version of Plot. Based on my hopes for the end result, I'd expect eyeColor on the second to last line to be an error, and for the empty string on the last line to autocomplete to one of name, hairColor, height, or shoeSize. Neither of these seems to be working. I'm not sure if I'm using the API wrong, or if something else is missing.
I found writing the type of data
to be a bit tricky. I'm not sure I got it right.
I also tried this less-typed version, which is probably closer to what we'll get in reality.
import { valueof } from "./options";
const data = [
{name: "Bob", hairColor: "red", height: 180, shoeSize: 11.5},
{name: "Sarah", hairColor: "green", height: 170, shoeSize: 7},
] as const;
valueof(data, "eyeColor");
valueof(data, "")
This did better. The usage of eyeColor gave me an error, though I still don't get field auto completions on the empty string. I think even this much would be a great boon to end users in the complete conversion.
// Some channels may allow a string constant to be specified; to differentiate | ||
// string constants (e.g., "red") from named fields (e.g., "date"), this | ||
// function tests whether the given value is a CSS color string and returns a | ||
// tuple [channel, constant] where one of the two is undefined, and the other is | ||
// the given value. If you wish to reference a named field that is also a valid | ||
// CSS color, use an accessor (d => d.red) instead. | ||
export function maybeColorChannel<T extends Datum>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Who is the target audience for this comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the internal comment from before
const TypedArray = Object.getPrototypeOf(Uint8Array); | ||
const objectToString = Object.prototype.toString; | ||
|
||
export function valueof<T extends undefined | null>(d: T, v: Accessor<T, any>, t?: ArrayType): T; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my testing, it seems that when VSCode gives type hints for a function with multiple overrides, it shows them in the order specified in the code. Is there anything else that should affect the order of these overrides? If not, I'd suggest ordering them based on how commonly we expect them to be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of them are more precise and must be before a less precise version that would catch the more precise case. So if we want to reorder them, we'll have to be extra careful.
@@ -16,7 +16,8 @@ export type Row = Record<string, Value>;
*/
export type Datum = Row | Value | Value[];
export type FieldNames<T> = T extends Row
- ? keyof T
+ ? // eslint-disable-next-line @typescript-eslint/ban-types
+ keyof T | (string & {})
: T extends Value[]
? // eslint-disable-next-line @typescript-eslint/ban-types
"length" | "0" | "1" | "2" | (string & {}) With this patch, we get autocomplete to work again, and the issue or "wrongfully giving undefined | null" above goes away too. However the price to pay is that we lose the ts error on: I think this makes sense. |
I hope we can restart work on this soon, with a simpler approach (not trying to pass the shape of data through all the code). |
Probably superseded by #1320 which goes the d.ts route, but would be nice to repurpose the type tests here? |
l33t tests at #1337 |
* tests salvaged from #1024 * fix crash in valueof when the data is not iterable * avoid the nullish test in map * move null test back to map * consolidate tests * remove "valid input data" type tests * test array value --------- Co-authored-by: Mike Bostock <[email protected]>
* tests salvaged from observablehq/plot#1024 * fix crash in valueof when the data is not iterable * avoid the nullish test in map * move null test back to map * consolidate tests * remove "valid input data" type tests * test array value --------- Co-authored-by: Mike Bostock <[email protected]>
* tests salvaged from observablehq/plot#1024 * fix crash in valueof when the data is not iterable * avoid the nullish test in map * move null test back to map * consolidate tests * remove "valid input data" type tests * test array value --------- Co-authored-by: Mike Bostock <[email protected]>
* tests salvaged from observablehq#1024 * fix crash in valueof when the data is not iterable * avoid the nullish test in map * move null test back to map * consolidate tests * remove "valid input data" type tests * test array value --------- Co-authored-by: Mike Bostock <[email protected]>
* tests salvaged from observablehq/plot#1024 * fix crash in valueof when the data is not iterable * avoid the nullish test in map * move null test back to map * consolidate tests * remove "valid input data" type tests * test array value --------- Co-authored-by: Mike Bostock <[email protected]>
Typescript for data (the expected shapes of data) and options (valueof, arrayify), with tooling and unit tests.
Was researched initially in #1008, and confirmed to work with all the transforms and more in #1005.