-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Infer literal types for string concatenations and similar expressions #13969
Comments
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.
This is currently rejected with error |
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 |
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
.The text was updated successfully, but these errors were encountered: