Closed donaldpipowitch closed 5 months ago
When
fooMediaQuery
is used I'd like to see@media(min-width: 800px)
as its type instead ofstring
.
This is interesting, mostly because it sounds like you are leveraging your editor's support of string literal types so that you can quickly glance at a type and get its content.
Yeah, when I work with CSS-in-JS solutions like glamor it is so great to immediately see some concrete value for different constants instead of just number or string.
import { css } from 'glamor';
const color = '#fff';
const mq = '@media(min-width: 800px)';
const myStyle = css({
[mq]: { // hover over `mq` → see '@media(min-width: 800px)'
color // hover over `color` → see '#fff'
}
});
If infering the value type doesn't work (e.g. because of templated strings) I need to duplicate the information into a comment which of course easily gets out of date, if someone changes the values without changing the comment.
import { css } from 'glamor';
const color = '#fff';
const breakpoint = '800px';
/**
* The media query is '@media(min-width: 800px)'.
*/
const mq = `@media(min-width: ${breakpoint})`;
const myStyle = css({
[mq]: { // hover over `mq` → see 'string' as its type and the comment which shows the value
color // hover over `color` → see '#fff'
}
});
I'd like to be able to do something like this, building a key using string literals:
type Obj = Record<"a" | "a1" | "b" | "b1", string>;
function getKey(useA: boolean, useOne: boolean): keyof Obj {
// [ts] Type 'string' is not assignable to type '"a" | "a1" | "b" | "b1"'.
return (useA ? "a" : "b") + (useOne ? "1" : "");
}
Adding a cast after the string concatenation makes the error go away, but doesn't actually check that my key generation is still valid if I change Obj.
Similar to @fjmorel, I'd love to have this distribute over a union. My use case is basically:
// i don't control the shape of x.
const x = { item1: true, item2: false, item3: true };
([1, 2, 3] as (1 | 2 | 3)[]).forEach(itemNum => {
// would love type inference here as item1 | item2 | item3
const itemKey = `item${itemNum}`;
});
This would be fantastic to see for indexing into objects with string literals, especially now that const assertions have been added in 3.4.
const obj= {
sourceName: "source",
sourceId: 1,
targetName: "target",
targetId: 2,
}
function getValues(prefix: "source" | "target") {
return { name: obj[prefix + "Name"], id: obj[prefix + "Id"] }
}
It'd be nice to be able to use either string literals or unions.
const bar = "bar";
const foobar = `foo${bar}`; // "foobar"
let union: "bar" | "baz";
const foobarOrFoobaz = `foo${union}`; // "foobar" | "foobaz"
let generic: string;
const stillGeneric = `foo${generic}`; // string
This would be helpful for string enums with a common prefix.
const prefix = "mymodule_"
export enum Actions {
actionOne: prefix + "action_one"
actionTwo: prefix + "action_two"
}
This is currently rejected with error TS2553: Computed values are not permitted in an enum with string valued members.
Maybe a const assertion syntax would suit this?
const bar = "bar"; // "bar"
const existingBehaviour = `foo-${bar}`; // string
const dynamic = process.env.BAR; // string | undefined
const existingBehaviourDynamic = `foo-${dynamic}`; // string
const barOrBaz = Math.round(Math.random()) ? "bar" : "baz"; // "bar" | "baz"
// A const assertion syntax…?
const fooBar = `foo-${bar}` as const; // "foo-bar"
const fooBarOrBaz = `foo-${barOrBaz}` as const; // "foo-bar" | "foo-baz"
const badDynamicVariable = `foo-${dynamic}` as const; // type error
this is not inferred yet, but now we at least have #40336 to represent string concatenation at the type level,
Worth noting that if you add as const
this should work now with template literal types!
This was fixed in #53907, which I believe has enough testing for this.
TypeScript Version: 2.1.5
Expected behavior:
Actual behavior:
Motivation
For constants which are created from other constants the IntelliSense is often more useful, when we see its value type instead of the "real" type.
More practical example:
When
fooMediaQuery
is used I'd like to see@media(min-width: 800px)
as its type instead ofstring
.