DefinitelyTyped/DefinitelyTyped 30116
The repository for high quality TypeScript type definitions.
Azure/bicep 470
ahejlsberg/typescript-build2016-demos 84
Collection of TypeScript demo projects form //build 2016
issue commentmicrosoft/TypeScript
New Error: assignability failure (material-ui)
This is working as intended and is an effect of type inference being more precise with the changes in the recursive conditional types PR. Previously we would only explore one level when inferring to the recursive CreateCSSProperties<Props> type. We now explore all the way down and get a match between the filter property in BaseCSSProperties and the filter method in string[]. The types really should be rewritten to not drill into arrays.
comment created time in 4 days
pull request commentmicrosoft/TypeScript
Allow pattern literal types like `http://${string}` to exist and be reasoned about
why don't we preserve the original type declaration instead of taking the product, and evaluate it when attempting assignment?
We favor the normalized string literal union representation because it enables more scenarios. For example, string literal union types can be unioned and intersected with other literal types, can narrow in control flow analysis, can be transformed using distributive conditional types, etc.
You're right that in certain cases that lead to very large cross products we might do better by preserving the un-normalized representation and match on that instead. It's an optimization we could consider, though I don't know how practical it is or how useful it would really be.
comment created time in 5 days
push eventmicrosoft/TypeScript
commit sha 5d6cce5ca7b15bec206f47c6e210d2460c47f6ba
Const contexts for template literals (#40707) * Support const assertions with template literal expressions * Add tests * Accept new baselines
push time in 6 days
PR merged microsoft/TypeScript
With this PR we produce template literal types for template literal expressions in const assertions.
const tc1 = 'foo' as const; // 'foo'
const tc2 = 'bar' as const; // 'bar'
const tc3 = `${tc1}-${tc2}` as const; // 'foo-bar'
const tc4 = [`${tc1}-${tc2}`, `${tc2}-${tc1}`] as const; // readonly ['foo-bar', 'bar-foo']
function test<T extends string, U extends string>(x: T, y: U) {
return `${x}-${y}` as const; // `${T}-${U}`
}
const ts1 = test('foo', 'bar'); // 'foo-bar'
const ts2 = test('foo', !!true ? '0' : '1'); // 'foo-0' | 'foo-1'
const ts3 = test(!!true ? 'top' : 'bottom', !!true ? 'left' : 'right'); // 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
The type of a template literal `aaa${x}bbb${y}ccc` in a const context is `aaa${X}bbb${Y}ccc`, where X and Y are the types of x and y respectively, or string when x or y is not assignable to string | number | boolean | bigint. Template literal types resulting from template literals in const contexts are normalized as described in #40336, meaning that a resulting type may actually be a union of literal types.
pr closed time in 6 days
Pull request review commentmicrosoft/TypeScript
Allow pattern literal types like `http://${string}` to exist and be reasoned about
namespace ts { checkSourceElement(span.type); const type = getTypeFromTypeNode(span.type); checkTypeAssignableTo(type, templateConstraintType, span.type); - if (!everyType(type, t => !!(t.flags & TypeFlags.Literal) || isGenericIndexType(t))) { + if (!everyType(type, t => !!(t.flags & TypeFlags.Literal) || isTypeAssignableTo(t, templateConstraintType))) {
This entire check and the error message can go away. It was there to catch the exact types string, number, and bigint, but we're good with those now.
comment created time in 6 days
Pull request review commentmicrosoft/TypeScript
Allow pattern literal types like `http://${string}` to exist and be reasoned about
namespace ts { } } } + else if (target.flags & TypeFlags.TemplateLiteral && source.flags & TypeFlags.StringLiteral) { + if (isPatternLiteralType(target)) { + // match all non-`string` segemnts
segments
comment created time in 6 days
Pull request review commentmicrosoft/TypeScript
Allow pattern literal types like `http://${string}` to exist and be reasoned about
namespace ts { accessNode; } + function isPatternLiteralTypeHoleType(type: Type) {
Let's call it isPatternLiteralPlaceholderType.
comment created time in 6 days
issue commentmicrosoft/TypeScript
Function parameter names are incorrectly inferred from variadiac tuples
Only way I can think of is to support inferring to consecutive variadic elements:
type Curry<A extends unknown[], R> = A extends [...infer Head, ...infer Tail] ? (...args: Head) => Curry<Tail, R> : R;
Currently we make no inferences in such cases because it isn't clear where to separate the source tuple, but we could consider a convention of inferring a single element tuple to the first position and a tuple with the remaining elements to the second position. This would be similar to what we do in template literal type inference.
comment created time in 6 days
pull request commentmicrosoft/TypeScript
Template literal types and mapped type 'as' clauses
@Roaders With #40707 we support template literal expressions in const contexts.
comment created time in 6 days
PR opened microsoft/TypeScript
With this PR we produce template literal types for template literal expressions in const assertions.
const tc1 = 'foo' as const; // 'foo'
const tc2 = 'bar' as const; // 'bar'
const tc3 = `${tc1}-${tc2}` as const; // 'foo-bar'
const tc4 = [`${tc1}-${tc2}`, `${tc2}-${tc1}`] as const; // readonly ['foo-bar', 'bar-foo']
function test<T extends string, U extends string>(x: T, y: U) {
return `${x}-${y}` as const; // `${T}-${U}`
}
const ts1 = test('foo', 'bar'); // 'foo-bar'
const ts2 = test('foo', !!true ? '0' : '1'); // 'foo-0' | 'foo-1'
const ts3 = test(!!true ? 'top' : 'bottom', !!true ? 'left' : 'right'); // 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
The type of a template literal `aaa${x}bbb${y}ccc` in a const context is `aaa${X}bbb${Y}ccc`, where X and Y are the types of x and y respectively, or string when x or y is not assignable to string | number | boolean | bigint. Template literal types resulting from template literals in const contexts are normalized as described in #40336, meaning that a resulting type may actually be a union of literal types.
pr created time in 6 days
issue commentmicrosoft/TypeScript
Inconsistent inference behaviour on union types
@RyanCavanaugh For that particular example I don't think you can soundly infer a union since find might mutate the array. But I get your point when the function is defined as
function find<T>(haystack: readonly T[], needle: T): number {
comment created time in 7 days
issue commentmicrosoft/TypeScript
Inconsistent inference behaviour on union types
We have a few ad hoc rules in place, such as always unioning literal types from the same domain, but otherwise, when no inference candidate is a supertype of all other inference candidates, we simply pick the first (for some meaning of first) candidate and leave it to the user to resolve the resulting errors though casts or explicit type arguments.
Ideally we would separately track inferences for mutable vs. read-only locations and produce union types whenever it is sound. For example:
declare function foo1<T>(a: T, b: T): T;
foo1('abc', 'def');
foo1('abc', 42); // Could soundly infer 'abc' | 42
function foo2<T>(a: T[], b: T[]) {
a[0] = b[0];
}
foo2(['abc' as const], [42 as const]); // No sound inference here
function foo3<T>(a: readonly T[], b: readonly T[]) {
a[0] = b[0]; // Error
}
foo3(['abc' as const], [42 as const]); // Could soundly infer 'abc' | 42
Some have made the argument that an error is preferable to a union type, even when a union type would be sound, because T is intended to represent a single type. For example, the error on foo1 is better than a union type because the a and b parameters are supposed to be of the same type. I'm not sure I buy that argument when a union type could soundly be inferred.
comment created time in 7 days
push eventmicrosoft/TypeScript
commit sha fbce4f6c989e4296ab43873ffc78e9c17809cac9
Intrinsic string types (#40580) * Introduce Uppercase<T> and Lowercase<T> intrinsic types * Accept new API baselines * Add Uppercase/Lowercase/Capitalize/Uncapitalize to lib.d.ts * Update fourslash * Add an 'intrinsic' keyword * Update template literal type tests * Accept new API baselines * Minor fixes * Switch Capitalize<T> and Uncapitalize<T> to intrinsic types * Add tests * Accept new baselines * Accept new baselines * Remove template literal type casing modifiers * Update tests * Accept new baselines * Add more tests * Normalize nested template literal types * Add normalization tests * Accept new baselines * Update tests
push time in 7 days
PR merged microsoft/TypeScript
This PR introduces four new intrinsic string mapping types in lib.es5.d.ts:
type Uppercase<S extends string> = intrinsic;
type Lowercase<S extends string> = intrinsic;
type Capitalize<S extends string> = intrinsic;
type Uncapitalize<S extends string> = intrinsic;
The new intrinsic keyword is used to indicate that the type alias references a compiler provided implementation. It is an error to specify intrinsic anywhere but immediately following the = separator in a type alias declaration for a type named Uppercase, Lowercase, Capitalize or Uncapitalize taking a single type parameter (but, of course, it is possible that additional intrinsic implementations will be provided in the future). There is generally no reason to ever use intrinsic in user code.
The intrinsic string types behave just like ordinary generic types and are similar to distributive conditional types in that they distribute over union types. Some examples:
type T10 = Uppercase<'hello'>; // "HELLO"
type T11 = Lowercase<'HELLO'>; // "hello"
type T12 = Capitalize<'hello'>; // "Hello"
type T13 = Uncapitalize<'Hello'>; // "hello"
type T20 = Uppercase<'foo' | 'bar'>; // "FOO" | "BAR"
type T21 = Lowercase<'FOO' | 'BAR'>; // "foo" | "bar"
type T22 = Capitalize<'foo' | 'bar'>; // "Foo" | "Bar"
type T23 = Uncapitalize<'Foo' | 'Bar'>; // "foo" | "bar"
type T30<S extends string> = Uppercase<`aB${S}`>;
type T31 = T30<'xYz'>; // "ABXYZ"
type T32<S extends string> = Lowercase<`aB${S}`>;
type T33 = T32<'xYz'>; // "abxyz"
type T34 = `${Uppercase<'abc'>}${Lowercase<'XYZ'>}`; // "ABCxyz"
type T40 = Uppercase<string>; // string
type T41 = Uppercase<any>; // any
type T42 = Uppercase<never>; // never
type T43 = Uppercase<42>; // Error, type 'number' does not satisfy the constraint 'string'
Note that the Capitalize<S> and Uncapitalize<S> intrinsic types could fairly easily be implemented in pure TypeScript using conditional types and template literal type inference, but it isn't practical to do so at the moment because we use ESLint which hasn't yet been updated to support template literal types (though we expect that to happen soon).
The intrinsic string types replace the uppercase, lowercase, capitalize, and uncapitalize modifiers in template literal types (based on feedback in #40336). This PR removes those modifiers.
pr closed time in 7 days
push eventmicrosoft/TypeScript
commit sha ce3dbef5f7424795cf6ef62f81f89b97bfa1a58d
Support properties of mapped types in assertion control flow analysis (#40482) * Support properties of mapped types in assertion control flow analysis * Add regression test * Accept new baselines
push time in 7 days
PR merged microsoft/TypeScript
Fixes #40346.
pr closed time in 7 days
issue closedmicrosoft/TypeScript
TypeScript Version: v4.1.0-dev.20200901
<!-- Search terms you tried before logging this (so others can find this issue more easily) --> Search Terms: readonly never return control flow
Code
interface Services {
panic(message: string): never; // note, returns 'never'
}
function foo(services: Readonly<Services>, s: string | null): string {
if (s === null) {
services.panic("ouch");
} else {
return s;
}
}
Expected behavior:
Should compile. Since services.panic() returns never, control flow analysis should allow this to compile.
Note that if you change the first param of function foo to services: Services instead of services: Readonly<Services>, it does compile.
Also note that this is not specific to Readonly — that was just the easiest way to demo the problem, and that is the scenario I'm actually hitting. Even if you make a no-op utility type, you see the same problem:
interface Services {
panic(message: string): never; // note, returns 'never'
}
// A no-op wrapper around a type
type Identity<T> = {
[P in keyof T]: T[P];
};
function foo(services: Identity<Services>, s: string | null): string {
if (s === null) {
services.panic("ouch");
} else {
return s;
}
}
Actual behavior:
Error: Function lacks ending return statement and return type does not include 'undefined'. (2366)
Playground Link: https://www.typescriptlang.org/play?ts=4.1.0-dev.20200901&ssl=5&ssc=24&pln=5&pc=33#code/JYOwLgpgTgZghgYwgAgMrQG7CQZ2QbwChkTkAHOEbACgFsIcc4BzCALmRzClGYEoOICBmgBuZAHoJyEAHtIAGmRQIYAK5QQeAORCRUbYQC+hQjDUgEYYLJDIYs2dRyZsDDgCUIcACa2ANgCeADzoUFi4AHxKOBxcPCDMyAA+Mmr+-gKc3LwExKTAMMjOyAC85WkZfHmktZyuuAB0FFQI1ABEsmoIABbtfKL5JEbIEP4uNXUkKuqanIO1JiZAA
Related Issues: Could not find any.
closed time in 7 days
mmoreartyPull request review commentmicrosoft/TypeScript
namespace ts { VoidIsNonOptional = 1 << 1, } + const enum IntrinsicTypeKind { + Uppercase, + Lowercase, + Capitalize, + Uncapitalize + } + + const intrinsicTypeKinds: ReadonlyESMap<string, IntrinsicTypeKind> = new Map(getEntries({
There are several "magic" types already that aren't intrinsic. For example Object, Function, Array<T>, Promise<T>, Iterator<T>, and others all receive special treatment in one way or another. The particular role "intrinsic" plays is to indicate that the implementation of the type is provided by the compiler. In the case of ThisType, there really is nothing interesting about the implementation because ThisType<T> is the same as T. All we do with ThisType is to take special hints when a reference to it occurs in a contextual type, but otherwise there's nothing special about it.
comment created time in 8 days
Pull request review commentmicrosoft/TypeScript
namespace ts { VoidIsNonOptional = 1 << 1, } + const enum IntrinsicTypeKind { + Uppercase, + Lowercase, + Capitalize, + Uncapitalize + } + + const intrinsicTypeKinds: ReadonlyESMap<string, IntrinsicTypeKind> = new Map(getEntries({
Why? ThisType is just a marker type that doesn't have any effect on its type argument. No reason to change it.
comment created time in 8 days
push eventmicrosoft/TypeScript
commit sha a5babe1c8fab6008559067218d3f5ab784fc85a3
Update package-lock.json
commit sha f66c8e6a69c5f482d7a9aac3396fb2e64e2874c9
Fix missing renamed compiler flags (#40606)
commit sha 02f500183956d403faaa4260241fa9cfc0470335
Update package-lock.json
commit sha d779a190535e52896cfe5100101173c00b6b8625
fix(40432): show as keyword in function context (#40481)
commit sha 735a67a05ea2b5844f7b0210af1df3e7ada71155
Fix iterable contextual type (#40592)
commit sha 0c08138490696c8fee4114f1a8dae0f74caa4715
Update package-lock.json
commit sha 6c6ddfe5c02194bc53ad70a2e08189f384373af6
fix(39899): include in NavigationBar default exported call expression arguments (#40412)
commit sha f1ac8cd93fcda3175366d7ed5e793d8083e1f372
Fix children prop for `react-jsx` and `react-jsxdev` (#40630) * Fix children prop for `react-jsx` and `react-jsxdev` * Add tests
commit sha c67fe4c2488320aa4c2b041173b28c71c5448727
LEGO: check in for master to temporary branch.
commit sha 8cdf5a20d949216837c3d6d7d13619b726c4be27
LEGO: Merge pull request 40641 LEGO: Merge pull request 40641
commit sha 17c7c261d429cdc0ec3f957eb7f342a852ef5fd2
Properly preserve modifiers in homomorphic mapped types with 'as' clauses (#40633) * Use original property name to fetch source property for modifiers * Add regression test * Accept new baselines
commit sha db2740ee82d90fd211eb34e1a5a0e30f34940e1b
Merge branch 'master' into intrinsicStringTypes
commit sha 4031f478a9176acf7e50b872dfaf06f9e91166e4
Update tests
push time in 8 days
push eventmicrosoft/TypeScript
commit sha d0fcddd79325dc33d451b5d26b947eb9714d7f95
Normalize nested template literal types
commit sha 3933ae94abf036fe3e0d934212b5b1a5259740b7
Add normalization tests
commit sha 43a249424442ebb0c2964b961d8f2cada2ae6f60
Accept new baselines
push time in 8 days
pull request commentmicrosoft/TypeScript
Allow pattern literal types like `http://${string}` to exist and be reasoned about
Templates placed into templates should essentially concatenate - good catch; I'm surprised we didn't already have that behavior.
We did have that behavior early on in the original PR, but I took it out when I added casing modifiers because it gets somewhat more complicated. However, the casing modifiers are going away in #40580, so I'll add the normalization logic back in there.
comment created time in 9 days
issue commentmicrosoft/TypeScript
Function parameter names are incorrectly inferred from variadiac tuples
The issue here is that only tuple types can carry along parameter names. In the example, though it is inferred from a tuple type, Head itself is not a tuple type, so any parameter name associated with the type is lost. It's not a trivial matter to preserve the name, though I agree it would be nice.
comment created time in 9 days
push eventmicrosoft/TypeScript
commit sha 17c7c261d429cdc0ec3f957eb7f342a852ef5fd2
Properly preserve modifiers in homomorphic mapped types with 'as' clauses (#40633) * Use original property name to fetch source property for modifiers * Add regression test * Accept new baselines
push time in 9 days
issue closedmicrosoft/TypeScript
Can't make mapped types with `as` clauses be homomorphic
I can't seem to find a way to make a mapped object type be homomorphic when it has an as clause.
type Getters<T> = {
[K in keyof T as `get${capitalize string & K}`]: () => T[K]
};
interface Person {
readonly name: string;
age: number;
location?: string;
}
type LazyPerson = Getters<Person>;
None of the modifiers from Person are preserved on LazyPerson. What is the right way to do this? Is there one?
closed time in 9 days
DanielRosenwasserpull request commentmicrosoft/TypeScript
Properly preserve modifiers in homomorphic mapped types with 'as' clauses
Merging following review with @DanielRosenwasser.
comment created time in 9 days
pull request commentmicrosoft/TypeScript
Allow pattern literal types like `http://${string}` to exist and be reasoned about
we can issue errors if the holes have non-string types in them in checked contexts
In the original PR there's logic to error when the type of a placeholder is exactly string, number, or bigint, so that's there already.
and if they get a non-string type via instantiation, do something like what we do for T[K] where K is non-property-key and return never as the result
So `${number}` would resolve to never or would stick around but not be compatible with anything? Either way seems even stranger than the string resolution we have now.
I'll say it again, I think the right solution here is to have ${number} and ${bigint} placeholders behave just like ${string} for purposes of matching, but then additionally require that the matched substring successfully parses as a number or bigint.
comment created time in 10 days
issue commentmicrosoft/TypeScript
Can't make mapped types with `as` clauses be homomorphic
Hmm, that's a bug. I'll work on a fix.
comment created time in 11 days
push eventmicrosoft/TypeScript
commit sha d5980d10d33433e9abd67d7cec750d080718227d
Add more tests
push time in 11 days
pull request commentmicrosoft/TypeScript
Allow pattern literal types like `http://${string}` to exist and be reasoned about
Given the existence of #40580, would it make sense to introduce a
ToString<T>intrinsic type to make that coercion more of a conversion?
That's a possibility, but what would ToString<number> resolve to? Presumably string, but then we still have the issue in #40538:
type Foo<T extends number> = `${ToString<T>}`;
const foo : Foo<number> = "bar"; // Huh?
comment created time in 11 days
pull request commentmicrosoft/TypeScript
Allow pattern literal types like `http://${string}` to exist and be reasoned about
What's the implementation for compatibility with
`${number}`?
The same as `${string}`, except we would require the matching substring to satisfy (+str).toString() === str. We already have a similar check in the isNumericLiteralName function in the compiler.
comment created time in 11 days
pull request commentmicrosoft/TypeScript
Allow pattern literal types like `http://${string}` to exist and be reasoned about
Plus, I think such holes are of little practical use, anyway - there's not really a demonstrated need for them, at least not yet
See #40538. We currently error on types like `${string}` and `${number}`, but we can't keep them from happening through instantiation. We need some behavior for them and our current behavior is not ideal. Hence my suggestion above.
comment created time in 11 days
issue commentmicrosoft/TypeScript
Literal / Known keyof T (especially for mapped types)
I think this accomplishes what you're looking for without any new features:
type MatchDottedPath<T, Path extends string, S = Path> =
Path extends keyof T ? S :
Path extends `${infer K}.${infer R}` ? K extends keyof T ? MatchDottedPath<T[K], R, S> : never :
never;
type PropType<T, Path extends string> =
Path extends keyof T ? T[Path] :
Path extends `${infer K}.${infer R}` ? K extends keyof T ? PropType<T[K], R> : unknown :
unknown;
declare function getProp<T, P extends string>(obj: T, path: MatchDottedPath<T, P>): PropType<T, P>;
let obj = { a: { b: { c: 42, d: 'hello' }}};
let p1 = getProp(obj, 'a.b'); // { c: number, d: string }
let p2 = getProp(obj, 'a.b.c'); // number
let p3 = getProp(obj, 'a.b.d'); // string
let p4 = getProp(obj, 'a.b.x'); // Error, 'string' is not assignable to 'never'
Arguably it would be nice to report a more explanatory error message for incorrect paths. We're thinking about ways to include a "reason" with never types, but nothing concrete yet.
comment created time in 12 days
pull request commentmicrosoft/TypeScript
Allow pattern literal types like `http://${string}` to exist and be reasoned about
I don't think we directly need to handle non-stringy holes quite so much. In fact, non-string holes I question the value of allowing at all; it feels very.... coercive, which consequently feels unsafe.
I think an argument can be made that we should handle ${number} and ${bigint} holes in relations, but have all inference results be strings (i.e. infer T positions are always constrained to string and there's no way to change that). I say this because it is already the case for ${boolean} holes, so we're halfway there already.
With respect to matching on ${number} positions, I think we should simply slurp up characters the same we we do for ${string} and then afterwards require that the string round trips.
comment created time in 12 days
pull request commentmicrosoft/TypeScript
Allow pattern literal types like `http://${string}` to exist and be reasoned about
I had code substantially similar to this in my branch for a while, but decided against keeping it in the initial PR. I really like the core concept if we can overcome the concerns I had. They are:
- This starts to feel like RegEx string literals, except not as powerful. Counterpoint of course is that we already have the functionality in inference and inference is supposed to reflect our type relations.
- What about union and intersection reduction involving these template literal pattern types? Take for example the intersection type
`get${string}` & ('getFoo' | 'setFoo'). Should that reduce to just'getFoo'?. What about`get${string}` & `${string}Prop`? Should that reduce to`get${string}Prop`? This could get complicated. - This will handle
${string}and we already handle patterns with${boolean}because that reduces to'true' | 'false'. But what about${number}and${bigint}. Seems like we need to support those as well, perhaps by saying we succeed for a string that is round trips to numeric and back to the same string representation. But then what about`${number}${number}`?. Should that infer a single digit similar to how we infer a single character for strings? And what about`${number}.{$string}`when inferring from'123.456'? Would we infer123.456for the number position, or just123? - If we support
${number}and${bigint}, how would it be possible to constrain aninfer Tdeclaration to only infer a number? Would we permit constraints ininferdeclarations, likeinfer T extends number?
In general I want to be as minimalistic as possible, but it is not entirely clear where to stop.
comment created time in 12 days
pull request commentmicrosoft/TypeScript
Would it make any sense to re-use
declare...
That's certainly looks reasonable, but unlike the current intrinsic solution, it would require a tool chain update because our grammar currently always requires an = and a type in a type alias declaration. For example, we'd need ESLint to be updated.
comment created time in 12 days
push eventmicrosoft/TypeScript
commit sha a5b3c611e4c606473931de4bdb10bc86d1464f7a
Remove template literal type casing modifiers
commit sha a405006a2e9b1a2e0b8146852140dabd2cf21fd8
Update tests
commit sha b46b3ec414ac889c34b6ba35e24f3180ca044ee1
Accept new baselines
push time in 12 days
push eventmicrosoft/TypeScript
commit sha de5e589be8efa278a1d4e4d2589f927f35bb6933
Accept new baselines
push time in 13 days
push eventmicrosoft/TypeScript
commit sha bbf26a07eb2ad8c5e117d6128f01e0a4c31f5687
Remove technically unnecessary 'module' option from 'harness' config. (#40526)
commit sha 9be710bbead42338f6bbf40b84003c2af176905e
LEGO: check in for master to temporary branch.
commit sha 5fa379c742c648cae63f0aa3b9c6219bab6aa615
LEGO: Merge pull request 40535 LEGO: Merge pull request 40535
commit sha e9d2aa1dd2affd0623cd74f4d22d1b21a421b5af
Update package-lock.json
commit sha ff5eef4ad4e6bcb69a7a952ac03d8c6f65bd3055
LEGO: check in for master to temporary branch.
commit sha 8d6aecbdde770aff9b4c228a182459f8ad24b973
LEGO: Merge pull request 40537 LEGO: Merge pull request 40537
commit sha 21d781fa548bb4e16f613822f85e50fb2ad27b1f
Fix incorrect name of index signature flag in implementation (#40541)
commit sha a6ea950c1b6d0b689554013df8d213ad0856a314
LEGO: check in for master to temporary branch.
commit sha d6859c3480a5a5c03515bc974652713e563b5b3e
LEGO: Merge pull request 40547 LEGO: Merge pull request 40547
commit sha 94123d5744cfd9ebf3755eae8cbbc973a741b1c5
Issue a diagnostic when the node builder performs truncation despite the `NoTruncation` flag being set (#40477)
commit sha c493d077a336d0f82c15b7e6dd6ac5c3aa347b1d
copy prologue directives to new file (#40306)
commit sha ec36d73e7a5c00df8eb865c95aef620d089ce783
Fix error on duplicate commonjs exports (#40545) * Fix error on duplicate commonjs exports Previously, the code missed setting the parent pointer for the lhs access expression. Also add declaration emit of element access expressions, missed in my previous PR. * Switch to excludes=None, add test case CommonJS exports have None excludes, but still have an error issued by the checker. This is the previous behaviour even though it would be nice to add some exclusions.
commit sha 575baf5c7fd100d6579446d8592d8cd1541dcfab
Support auto-import from paths alias without baseUrl (#40546)
commit sha 85553ec56476331af43c061fa751c9c640324d34
LEGO: check in for master to temporary branch.
commit sha 7db91182f70b3e3f7f018107fc0d4bc269f65f4c
LEGO: Merge pull request 40563 LEGO: Merge pull request 40563
commit sha dba042d7d5f544862a883f281dbe1911273ab47d
Add quick fix to add 'void' to Promise resolved without value (#40558) * Add codefix to add 'void' to Promise resolved without value * Add specific error message in checker to reduce quick-fix time in editor
commit sha d40663f7e56a203b5a298fedf60323d5b29a235e
Pull all history in branch sync script This got broken when it got updated to checkout@v2, which by default only checks out the specified ref and none of its history.
commit sha 98314d77e8d60f179ee6fe90c55dccb6a741473d
Use unexpanded parameter list in serialization when the expanded list has a non-trailing variadic position (#40556)
commit sha ca7c4137502b0f87135fbb1db60ed2c3bb1ca4e9
LEGO: check in for master to temporary branch.
commit sha b908d6698ece73946fa6585562abf0ca014576a1
LEGO: Merge pull request 40566 LEGO: Merge pull request 40566
push time in 13 days
PR opened microsoft/TypeScript
This PR introduces four new intrinsic string mapping types in lib.es5.d.ts:
type Uppercase<S extends string> = intrinsic;
type Lowercase<S extends string> = intrinsic;
type Capitalize<S extends string> = intrinsic;
type Uncapitalize<S extends string> = intrinsic;
The new intrinsic keyword is used to indicate that the type alias references a compiler provided implementation. It is an error to specify intrinsic anywhere but immediately following the = separator in a type alias declaration for a type named Uppercase, Lowercase, Capitalize or Uncapitalize taking a single type parameter (but, of course, it is possible that additional intrinsic implementations will be provided in the future).
The intrinsic string types behave just like ordinary generic types and are similar to distributive conditional types in that they distribute over union types. Some examples:
type T10 = Uppercase<'hello'>; // "HELLO"
type T11 = Lowercase<'HELLO'>; // "hello"
type T12 = Capitalize<'hello'>; // "Hello"
type T13 = Uncapitalize<'Hello'>; // "hello"
type T20 = Uppercase<'foo' | 'bar'>; // "FOO" | "BAR"
type T21 = Lowercase<'FOO' | 'BAR'>; // "foo" | "bar"
type T22 = Capitalize<'foo' | 'bar'>; // "Foo" | "Bar"
type T23 = Uncapitalize<'Foo' | 'Bar'>; // "foo" | "bar"
type T30<S extends string> = Uppercase<`aB${S}`>;
type T31 = T30<'xYz'>; // "ABXYZ"
type T32<S extends string> = Lowercase<`aB${S}`>;
type T33 = T32<'xYz'>; // "abxyz"
type T34 = `${Uppercase<'abc'>}${Lowercase<'XYZ'>}`; // "ABCxyz"
type T40 = Uppercase<string>; // string
type T41 = Uppercase<any>; // any
type T42 = Uppercase<never>; // never
type T43 = Uppercase<42>; // Error, type 'number' does not satisfy the constraint 'string'
Note that the Capitalize<S> and Uncapitalize<S> intrinsic types could fairly easily be implemented in pure TypeScript using conditional types and template literal type inference, but it isn't practical to do so at the moment because we use ESLint which hasn't yet been updated to support template literal types (though we expect that to happen soon).
The intrinsic string types are intended to replace the uppercase, lowercase, capitalize, and uncapitalize modifiers in template literal types (based on feedback in #40336). They will be removed in a separate PR.
pr created time in 13 days
pull request commentmicrosoft/TypeScript
Merge identical object types when discriminating contextual types
maybe I can tweak the contextual type discrimination rules a bit to allow structurally identical members, instead?
Definitely think you're better off with that strategy.
comment created time in 13 days
pull request commentmicrosoft/TypeScript
Merge identical object types when discriminating contextual types
I'm not surprised. material-ui has some very large types that are very similar, and the identical object types check is an O^2 structural check that quickly generates lots of work.
comment created time in 13 days
issue commentmicrosoft/TypeScript
Bug: (Any) string is assignable to numeric templated literal type
Here's how I'd write it:
type MatchDigit<D extends string> =
D extends '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ? D : never;
type MatchInteger<S extends string, T = S> =
S extends `${MatchDigit<infer _D>}${infer R}` ? R extends '' ? T : MatchInteger<R, T> : never;
type MatchDecimal<S extends string> =
S extends `${'' | '+' | '-'}${MatchInteger<infer _I>}` ? S :
S extends `${'' | '+' | '-'}${MatchInteger<infer _I>}.${MatchInteger<infer _F>}` ? S :
never;
type MatchExtent<S extends string> =
S extends `${MatchDecimal<infer _>}${'px' | 'pt'}` ? S : never;
declare function takeExtent<S extends string>(ex: MatchExtent<S>): void;
takeExtent('100px');
takeExtent('-1px');
takeExtent('9.5pt');
Note the trick of applying the matching productions to the infer X placeholders. This works as long as each production resolves to its own type argument in one of its branches (because when inferring to a conditional type we infer to each of the branches). Also note that the validation happens during type inference, not during relationship checking. That means it isn't possible to declare a type Extent and have validation occur in assignments.
comment created time in 14 days
issue commentmicrosoft/TypeScript
Bug: (Any) string is assignable to numeric templated literal type
This is working as intended, but could be a suggestion. The instantiation Foo<number> resolves to `${number}` which then resolves to string (we do the same when a placeholder is instantiated to string or bigint).
We could consider keeping templates such as `${number}` or `start-${string}-end` around and introduce assignability rules similar to what we do in type inference. I had some of that in place at one time, but was concerned it leads us down the slippery slope towards full on regular expression types. But we're sort of there already because of type inference, so maybe.
comment created time in 14 days
push eventmicrosoft/TypeScript
commit sha 57c8938d9e90dd4ece5389d4c78593db1ea22e81
Consistent inferences when inferring to template literal type (#40518) * Consistently make inferences when inferring to template literal type * Add tests * Accept new baselines
push time in 16 days
delete branch microsoft/TypeScript
delete branch : consistentTemplateLiteralInference
delete time in 16 days
PR merged microsoft/TypeScript
This PR makes a minor adjustment to template literal inference to make results more consistent:
type Foo<T> = T extends `*${infer S}*` ? S : never;
type T1 = Foo<any>; // never (previously string)
type T2 = Foo<string>; // never (previously string)
type T3 = Foo<'abc'>; // never
type T4 = Foo<'*abc*'>; // 'abc'
Inference now consistently infers never for all placeholder type variables when the source string isn't a literal type that matches the pattern.
pr closed time in 16 days
push eventmicrosoft/TypeScript
commit sha 8aad412c9ecf30323f77a8cda4fa25392c8d2b7b
Added zero-padding to timestamp output
commit sha bbf2133fbef7c87591f2e3e9b40a49004589deda
Update package-lock.json
commit sha cdafb7157b7954f78a4ec82543fd2ca691f0ba39
Replaces the default module index resolver with '/index' instead of '' when handling internal routing for dts bundles (#39277) * Adds support for declaring the bundled name of a dts module export Co-authored-by: Wesley Wigham <[email protected]> * Adds baselines * Update the tests * Try to reduce the scope of the bundledPackageName error * Use the flag in more baselines * Get it green * More tests * Handle more feedback * More test cleanup * Set the moduleResolution for the tsconfigs Co-authored-by: Wesley Wigham <[email protected]>
commit sha 07c92e8fcaa50d6c1866403469b8ba25780f0128
Modified existing padLeft() and padRight() functions to support strings other than a single space as padding. Used this new functionality to zero-pad the timestamp created by nowString().
commit sha ce1d76c7c909b5e91882f22634df48d161918382
Merge branch 'master' of https://github.com/microsoft/TypeScript
commit sha 4a3b1957727625720eb48a83ee2dca42c55eda17
Add lib es2020.sharedmemory (#39541)
commit sha 083129f005ac0e40b96701c7928434e8aee40655
A union including non-iterable types is not iterable (#40350) * WIP * If method type derives solely from the global iterator or generator type, use its type arguments * Add test for problem fixed as side effect
commit sha a36f17c1f8dc08b8acf5c7b2d87b502c86310961
Add emit support for jsx/jsxs experimental jsx runtime api (#39199)
commit sha db5368dc1d8543d73fbfa37ba4cb82dc94a26635
Import the semantic highlighter from typescript-vscode-sh-plugin (#39119) * Initial import of the vscode semantic highlight code * Adds the ability to test modern semantic classification via strings instead of numbers * Adds existing tests * Port over the semantic classification tests * Update baselines * Update src/harness/fourslashImpl.ts Co-authored-by: Nathan Shively-Sanders <[email protected]> * Handle feedback from #39119 * Consistent formatting in the 2020 classifier * Update baselines * Apply suggestions from code review Co-authored-by: Daniel Rosenwasser <[email protected]> * Update src/harness/fourslashImpl.ts Co-authored-by: Daniel Rosenwasser <[email protected]> * Reafactor after comments * Use 2020 everywhere * Handle feedback * WIP - don't provide a breaking change * Fix all build errors * Update baselines * Update src/services/classifier2020.ts Co-authored-by: Sheetal Nandi <[email protected]> * Addresses Ron's feedback Co-authored-by: Nathan Shively-Sanders <[email protected]> Co-authored-by: Daniel Rosenwasser <[email protected]> Co-authored-by: Sheetal Nandi <[email protected]>
commit sha aa2756a5d7f5ed02e6c676e0fd8e4d1a5e0acd13
Updates Dom lib with TSJS changes, adding a new library for webworker iterable (#40500) * Updates Dom lib with TSJS changes, adding a new library for webworker iterable Co-authored-by: Nathan Shively-Sanders <[email protected]> * Fixes tests Co-authored-by: Nathan Shively-Sanders <[email protected]>
commit sha 9c8d11b5edad272c8ff17c81b5d3a385efc5443a
Allow 'paths' without 'baseUrl' (#40101) * Allow paths without baseUrl * Remove exception for leading * paths * Add comment, remove commented code * Update baselines * Remove unnecessary default * Fix test harness * Fix baseline * Resolve relative to host.getCurrentDirectory() with createProgram API
commit sha 3d235b42a0f31d3529d70d7649f1157a84293e1f
--noUncheckedIndexedAccess (#39560) * Initial implementation + tests * linty * Support destructuring declarations and assignments * lint * Fix destructuring assignment and element access into known properties * Update baselines * Rename flag to unUncheckedIndexedAccess * Add test for unique symbol indexing * Fix flag order in baselines Co-authored-by: Andrew Branch <[email protected]>
commit sha d7cd405bb23eacda2833f3e7fe1be6d1b377f882
feat(14751): show static members at the top of the list for a class like completion (#40428)
commit sha 4c5e463e1216e0b696fb0c3bf50efecb1fe86252
Simplifying padLeft() to only allow spaces or zeros for padding. Updated padRight() to mirror padLeft() but without the option to use zeros since that would be an unlikely use case.
commit sha ea51fabb7c97dbf83fc230606f19a67fd375460a
Don't crash when observing invalid 'export' in object literal (#40295) Fixes #32870
commit sha eee799fe0cf52ced3acec1e3a0423dc3c4c733ea
Properly check types in template literal placeholders (#40498) * Properly check types in template literal placeholders * Add regression test * Update test * Accept new baselines
commit sha 9c99870058f8e2b86ef55dce809e4915794d5325
Support element access aliases: exports["x"] = x (#40514)
commit sha 46506b5872aacfb60bf482abca0dbdef444da29a
Merge pull request #40095 from rhillefeld/master Added zero-padding to timestamp output
commit sha c9422e6aa14965b2ca938ad26f84a9164a324cfd
Update package-lock.json
commit sha a3a2db2900fe205783e89ad176d7f119b4eb5962
Merge branch 'master' into consistentTemplateLiteralInference # Conflicts: # tests/baselines/reference/templateLiteralTypes1.errors.txt # tests/baselines/reference/templateLiteralTypes1.symbols
push time in 16 days
push eventmicrosoft/TypeScript
commit sha db4adfdd861cf8e0c5d59fe9131661b38e43917e
Add tests
commit sha 0ab5513b14b1381630e86e3b805acf0bb1cee05c
Accept new baselines
push time in 16 days
PR opened microsoft/TypeScript
This PR makes a minor adjustment to template literal inference to make results more consistent:
type Foo<T> = T extends `*${infer S}*` ? S : never;
type T1 = Foo<any>; // never (previously string)
type T2 = Foo<string>; // never (previously string)
type T3 = Foo<'abc'>; // never
type T4 = Foo<'*abc*'>; // 'abc'
Inference now consistently infers never for all placeholder type variables when the source string isn't a literal type that matches the pattern.
pr created time in 16 days
create barnchmicrosoft/TypeScript
branch : consistentTemplateLiteralInference
created branch time in 16 days
push eventmicrosoft/TypeScript
commit sha eee799fe0cf52ced3acec1e3a0423dc3c4c733ea
Properly check types in template literal placeholders (#40498) * Properly check types in template literal placeholders * Add regression test * Update test * Accept new baselines
push time in 17 days
PR merged microsoft/TypeScript
Fixes issue reported here.
pr closed time in 17 days
pull request commentmicrosoft/TypeScript
Support properties of mapped types in assertion control flow analysis
Tests all look clean (but, boy, the community code test suite just has a ton of existing issues that make it super hard to compare).
comment created time in 17 days
pull request commentmicrosoft/TypeScript
Template literal types and mapped type 'as' clauses
@Roaders The following works:
type StringWithId<T extends string> = T extends `row_${infer _}` ? T : never;
declare function parseId<T extends string>(value: StringWithId<T>): void;
declare const s: string;
parseId("helloWorld"); // Error
parseId("row_one"); // Ok
parseId(s); // Ok
If you want an error on the last line, you can use this declaration:
type StringWithId<T extends string> = string extends T ? never : T extends `row_${infer _}` ? T : never;
comment created time in 17 days
pull request commentmicrosoft/TypeScript
Support properties of mapped types in assertion control flow analysis
@typescript-bot test this @typescript-bot user test this @typescript-bot run dt
comment created time in 18 days
pull request commentmicrosoft/TypeScript
Template literal types and mapped type 'as' clauses
@davidmurdoch That should be an error. Thanks for catching!
comment created time in 18 days
issue commentmicrosoft/TypeScript
Technically this is a design limitation, but it is subtle. As explained in #32695, in order to avoid control flow analysis circularities we have some fairly stringent rules for how a function or method needs to be declared in order to be considered in the assertion and never-returning analysis. In this particular case, the services.panic reference fails to meet the requirements because panic isn't declared with an explicit type annotation (rather, it's type is computed from mapping a property in another type).
It wouldn't be too hard to support this particular case (i.e. we could allow properties with types that result from mapping another property with an explicit type annotation). I will put up a PR for that.
comment created time in 18 days
PR closed microsoft/TypeScript
<!-- Thank you for submitting a pull request!
Please verify that:
- [x] There is an associated issue in the
Backlogmilestone (required) - [x] Code is up-to-date with the
masterbranch - [ ] You've successfully run
gulp runtestslocally - [ ] There are new or updated unit tests validating the change
Refer to CONTRIBUTING.MD for more details. https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md -->
Fixes #23689
This PR is based on #40336 (Template string types and mapped type 'as' clauses) so it doesn't use master as the base branch.
This PR introduces:
- A new type-level expression:
throw type_expr. Currentlythrowtype only throws in a conditional type. - A new modifier to use in the template string
typeof Tto make it easier to debug.
Considered use cases:
Welcome to suggest more use cases!
TypeAlias instantation
type MustNumber<T> = T extends number ? T : throw `Expected, but found "${typeof T}"`
type A = MustNumber<1>
type B = MustNumber<typeof window>

Prevent CallExpression
class X<T> {
constructor(public item: T) { }
add(a: T): T extends number | string | bigint ? T : throw `Cannot apply + operator on this type` {
// @ts-ignore
return a + this.item
}
}
new X(1).add(2).toExponential()
new X("").add("")
new X({}).add({})

TODO:
- [x] Figure out how to "print" types in the error message. Maybe a new modifier
\${typeof T}`` - [ ] Write tests and fix broken parts
- [ ] Wait for #40336 to be merged
pr closed time in 19 days
pull request commentmicrosoft/TypeScript
Template literal types and mapped type 'as' clauses
Merging this PR in preparation for 4.1 beta. We hear the feedback on uppercase, lowercase, etc. modifiers and will continue to think about more general solutions.
comment created time in 19 days
push eventmicrosoft/TypeScript
commit sha 6f0c91c4cbb2f6a4cda1e77ca96f0652903bde1a
Template literal types and mapped type 'as' clauses (#40336) * Initial implementation of string template types * Accept new API baselines * Accept new baselines * Unified checking for large cross product union types * Accept new baselines * Ensure errors from union type resolution are reported * Accept new baselines * Compute constraints for string template types * Support `as T` clause in mapped types * Accept new API baselines * Add missing semicolon * Add checking of `as T` clauses * Support casing modifiers in string template types * Accept new baselines * Bump keyword maximum length * fix anders * Revert "fix anders" This reverts commit b3178d46184c068b7b83008ad98a52faac1e8a34. * Properly handle 'as T' clause with keyof for mapped type * Fix lint error * Single character inferences and anchored end span matching * Fewer array copy operations in template literal type resolution * Handle cases where 'as T' maps multiple properties onto one * Fix lint error * Store key type instead of type mapper in MappedSymbol * No constraint on `in T` type when `as N` clause present * Rename from TemplateType to TemplateLiteralType * Accept new API baselines * Add tests * Accept new baselines * Address CR feedback * Accept new API baselines Co-authored-by: Erich Gamma <[email protected]>
push time in 19 days
issue closedmicrosoft/TypeScript
Augment Key during Type Mapping
Aurelia follows the convention that for any field foo, when foo is changed by the framework, then an attempt to call fooChanged() is made. There is (seemingly) no way to describe this convention as a type (automatically) via the Mapped Type functionality alone.
I would like to open discussion to the prospect of augmenting property keys during mapping.
For example: via arthimetic:
type Changed<T> =
{
[ P in keyof T ] + "Changed" ?: Function;
}
class Foo{
field:number;
}
let foo = <Foo & Changed<Foo>> new Foo();
foo.field = 10;
if(foo.fieldChanged)
foo.fieldChanged();
in this use-case specifically it probably would require https://github.com/Microsoft/TypeScript/issues/12424 too, but that is beside the point here.
closed time in 19 days
MeirionHughesPR merged microsoft/TypeScript
This PR implements two new features:
- Template literal types, which are a form of string literals with embedded generic placeholders that can be substituted with actual string literals through type instantiation, and
- Mapped type
asclauses, which provide the ability to transform property names in mapped types.
Template literal types
Template literal types are the type space equivalent of template literal expressions. Similar to template literal expressions, template literal types are enclosed in backtick delimiters and can contain placeholders of the form ${T}, where T is a type that is assignable to string, number, boolean, or bigint. Template literal types provide the ability to concatenate literal strings, convert literals of non-string primitive types to their string representation, and change the capitalization or casing of string literals. Furthermore, through type inference, template literal types provide a simple form of string pattern matching and decomposition.
Template literal types are resolved as follows:
- Union types in placeholders are distributed over the template literal type. For example
`[${A|B|C}]`resolves to`[${A}]` | `[${B}]` | `[${C}]`. Union types in multiple placeholders resolve to the cross product. For example`[${A|B},${C|D}]`resolves to`[${A},${C}]` | `[${A},${D}]` | `[${B},${C}]` | `[${B},${D}]`. - String, number, boolean, and bigint literal types in placeholders cause the placeholder to be replaced with the string representation of the literal type. For example
`[${'abc'}]`resolves to`[abc]`and`[${42}]`resolves to`[42]`. - Any one of the types
any,string,number,boolean, orbigintin a placeholder causes the template literal to resolve to typestring. - The type
nevertype in a placeholder causes the template literal to resolve tonever.
Some examples:
type EventName<T extends string> = `${T}Changed`;
type Concat<S1 extends string, S2 extends string> = `${S1}${S2}`;
type ToString<T extends string | number | boolean | bigint> = `${T}`;
type T0 = EventName<'foo'>; // 'fooChanged'
type T1 = EventName<'foo' | 'bar' | 'baz'>; // 'fooChanged' | 'barChanged' | 'bazChanged'
type T2 = Concat<'Hello', 'World'>; // 'HelloWorld'
type T3 = `${'top' | 'bottom'}-${'left' | 'right'}`; // 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
type T4 = ToString<'abc' | 42 | true | -1234n>; // 'abc' | '42' | 'true' | '-1234'
Beware that the cross product distribution of union types can quickly escalate into very large and costly types. Also note that union types are limited to less than 100,000 constituents, and the following will cause an error:
type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
type Zip = `${Digit}${Digit}${Digit}${Digit}${Digit}`; // Error
A template literal placeholder may optionally specify an uppercase, lowercase, capitalize, or uncapitalize modifier before the type. This modifier changes the casing of the entire replacement string or the first character of the replacement string. For example:
type GetterName<T extends string> = `get${capitalize T}`;
type Cases<T extends string> = `${uppercase T} ${lowercase T} ${capitalize T} ${uncapitalize T}`;
type T10 = GetterName<'foo'>; // 'getFoo'
type T11 = Cases<'bar'>; // 'BAR bar Bar bar'
type T12 = Cases<'BAR'>; // 'BAR bar BAR bAR'
Template literal types are all assignable to and subtypes of string. Furthermore, a template literal type `${T}` is assignable to and a subtype of a template literal type `${C}`, where C is a string literal type constraint of T. For example:
function test<T extends 'foo' | 'bar'>(name: `get${capitalize T}`) {
let s1: string = name;
let s2: 'getFoo' | 'getBar' = name;
}
Type inference supports inferring from a string literal type to a template literal type. For inference to succeed the starting and ending literal character spans (if any) of the target must exactly match the starting and ending spans of the source. Inference proceeds by matching each placeholder to a substring in the source from left to right: A placeholder followed by a literal character span is matched by inferring zero or more characters from the source until the first occurrence of that literal character span in the source. A placeholder immediately followed by another placeholder is matched by inferring a single character from the source.
Some examples:
type MatchPair<S extends string> = S extends `[${infer A},${infer B}]` ? [A, B] : unknown;
type T20 = MatchPair<'[1,2]'>; // ['1', '2']
type T21 = MatchPair<'[foo,bar]'>; // ['foo', 'bar']
type T22 = MatchPair<' [1,2]'>; // unknown
type T23 = MatchPair<'[123]'>; // unknown
type T24 = MatchPair<'[1,2,3,4]'>; // ['1', '2,3,4']
type FirstTwoAndRest<S extends string> = S extends `${infer A}${infer B}${infer R}` ? [`${A}${B}`, R] : unknown;
type T25 = FirstTwoAndRest<'abcde'>; // ['ab', 'cde']
type T26 = FirstTwoAndRest<'ab'>; // ['ab', '']
type T27 = FirstTwoAndRest<'a'>; // unknown
Template literal types can be combined with recursive conditional types to write Join and Split types that iterate over repeated patterns.
type Join<T extends (string | number | boolean | bigint)[], D extends string> =
T extends [] ? '' :
T extends [unknown] ? `${T[0]}` :
T extends [unknown, ...infer U] ? `${T[0]}${D}${Join<U, D>}` :
string;
type T30 = Join<[1, 2, 3, 4], '.'>; // '1.2.3.4'
type T31 = Join<['foo', 'bar', 'baz'], '-'>; // 'foo-bar-baz'
type T32 = Join<[], '.'>; // ''
type Split<S extends string, D extends string> =
string extends S ? string[] :
S extends '' ? [] :
S extends `${infer T}${D}${infer U}` ? [T, ...Split<U, D>] :
[S];
type T40 = Split<'foo', '.'>; // ['foo']
type T41 = Split<'foo.bar.baz', '.'>; // ['foo', 'bar', 'baz']
type T42 = Split<'foo.bar', ''>; // ['f', 'o', 'o', '.', 'b', 'a', 'r']
type T43 = Split<any, '.'>; // string[]
The recursive inference capabilities can for example be used to strongly type functions that access properties using "dotted paths", and pattern that is sometimes used in JavaScript frameworks.
type PropType<T, Path extends string> =
string extends Path ? unknown :
Path extends keyof T ? T[Path] :
Path extends `${infer K}.${infer R}` ? K extends keyof T ? PropType<T[K], R> : unknown :
unknown;
declare function getPropValue<T, P extends string>(obj: T, path: P): PropType<T, P>;
declare const s: string;
const obj = { a: { b: {c: 42, d: 'hello' }}};
getPropValue(obj, 'a'); // { b: {c: number, d: string } }
getPropValue(obj, 'a.b'); // {c: number, d: string }
getPropValue(obj, 'a.b.d'); // string
getPropValue(obj, 'a.b.x'); // unknown
getPropValue(obj, s); // unknown
Mapped type as clauses
With this PR, mapped types support an optional as clause through which a transformation of the generated property names can be specified:
{ [P in K as N]: X }
where N must be a type that is assignable to string | number | symbol. Typically, N is a type that transforms P, such as a template literal type that uses P in a placeholder. For example:
type Getters<T> = { [P in keyof T & string as `get${capitalize P}`]: () => T[P] };
type T50 = Getters<{ foo: string, bar: number }>; // { getFoo: () => string, getBar: () => number }
Above, a keyof T & string intersection is required because keyof T could contain symbol types that cannot be transformed using template literal types.
When the type specified in an as clause resolves to never, no property is generated for that key. Thus, an as clause can be used as a filter:
type Methods<T> = { [P in keyof T as T[P] extends Function ? P : never]: T[P] };
type T60 = Methods<{ foo(): number, bar: boolean }>; // { foo(): number }
When the type specified in an as clause resolves to a union of literal types, multiple properties with the same type are generated:
type DoubleProp<T> = { [P in keyof T & string as `${P}1` | `${P}2`]: T[P] }
type T70 = DoubleProp<{ a: string, b: number }>; // { a1: string, a2: string, b1: number, b2: number }
Fixes #12754.
Playground: https://www.typescriptlang.org/play?ts=4.1.0-pr-40336-88
pr closed time in 19 days
push eventmicrosoft/TypeScript
commit sha cea1cfb82edde53d9d1b3280a193fc1bb549e431
Consistently error when rest element isn't last in tuple type (#40254) * Consistently error when rest element isn't last in tuple type * Add regression test * Accept new baselines * Stricter circular recursion check in type inference * Revert "Stricter circular recursion check in type inference" This reverts commit 80e6df6230ffc4f2416e23759c0749aa1cebf5d1. * Revert "Accept new baselines" This reverts commit 355706dadc8d2eb30f283e927d52d13736f6dd65. * Accept new baselines
commit sha 7838b0172a36c10cdc16ff3b4cef2fe55f705379
Add errors when providing type arguments for intrinsic JSX tags (#40293)
commit sha 68d4505679cd25221df5e74b6d9b1734ed5765d7
LEGO: check in for master to temporary branch.
commit sha 42196df2f3a3aabee05a0612a2a3e92b31ca8826
LEGO: Merge pull request 40437 LEGO: Merge pull request 40437
commit sha 1d2278be0551661c34610331e1ee9b48acf24125
Remove trailing space from Gulpfile.js comment (#40199)
commit sha fa89ce61589261251ed8bd70e7e58d86cdca0ec6
Remove assignability cases in getNarrowedType + an isArray improvement for readonly arrays (#39258) * Explore using a different isArray declaration * Add tests and the new isArray definition * Baseline updates * Upda the isArray type
commit sha 15084465b7be3095095e07ce3ac5bd58499e9327
fix(40222): fix crash on using destructuring in a catch clause (#40240)
commit sha 6101fbca39795c599cc9676615ea4da5c3b135b1
fix(40150): use parameter name for a Promise callback function (#40191)
commit sha 6aec7f46766711e1a437aa5032f7cb7c333dc0e7
feat(25770): add Quick Fix to convert LiteralType to MappedType (#40226)
commit sha 2b0278a88f766e87bd0fb839b1048d1e17894969
Update package-lock.json
commit sha 4584d6d47095bf2a53f6c1724da48a2ebd09b160
fix(39676): skip removing unused parameters for functions used as callback references (#40299)
commit sha ee5f51bc0fc06964f2ba27217b5555a82a398673
Add see tag support (#39760) * Add see tag parser * add baseline * fix symbol resolve * add more case * fix unittests * improve tests and parser * accept baseline * Adopt package-lock.json and npm ci * Add a workflow to update package-lock.json daily * Git ignore package-lock.json and forcibly update in workflow * Update bot email address * Delete extra npm update * Update package-lock.json * Add compactDisplay and signDisplay to NumberFormatOptions (#40039) * Fix typo in (Readonly)Set.keys comment (fixes #40164) (#40176) * fix(26325): use a unique name for reserved words in 'constructor like' function name (#39684) * fix(25770): add diagnostic message for the possible mapped type used as an index (#39973) * fix(31046): add new diagnostic message for incompatible constructor signature (#40073) * Update package-lock.json * Update package-lock.json * Add rename support * Accpet baseline * wip * fix anders * Revert "fix anders" This reverts commit b3178d46184c068b7b83008ad98a52faac1e8a34. * Fix call hierarchy item serialization and server tests (#40348) * Avoid error * accept baseline * Add more tests * Add signature name resolve Co-authored-by: Andrew Casey <[email protected]> Co-authored-by: TypeScript Bot <[email protected]> Co-authored-by: Neil Kistner <[email protected]> Co-authored-by: cherryblossom000 <[email protected]> Co-authored-by: Alexander T <[email protected]> Co-authored-by: Erich Gamma <[email protected]> Co-authored-by: Andrew Branch <[email protected]>
commit sha 96b0832cf6fa109c3e37ff4189eb599afb14690f
fix(40322): bad completions for string literal type as indexed access type object (#40424) * Added fourslash tests to work on the bug * fix(40322): bad completions for string literal type as indexed access type object * Added regression tests * Using nodes instead of text * Add verification for parenthesized nodes * Using range check * Change test markers
commit sha 6bd94b05d2e7d78f21074186775e5891385adaab
Merge branch 'master' of https://github.com/microsoft/TypeScript
commit sha d38a3880d4a65be90fe1abee9d6d96f2819e399d
Merge branch 'master' into templateTypes # Conflicts: # tests/baselines/reference/api/tsserverlibrary.d.ts # tests/baselines/reference/api/typescript.d.ts
push time in 19 days
push eventmicrosoft/TypeScript
commit sha 6c9595131230805e9206ab2d497d82ae5c255e4a
Address CR feedback
commit sha e81ebb4fa3d63ed8bacf6cc55398ff810ba08642
Accept new API baselines
push time in 19 days
pull request commentmicrosoft/TypeScript
Template literal types and mapped type 'as' clauses
@jcalz The new mapped type as clause can be used to make FromEntries even simpler:
type FromEntries<T extends [keyof any, any]> = { [K in T as K[0]]: K[1] };
type NamedRepo<T, Sing extends string, Plur extends string> = FromEntries<
[`get${Plur}`, () => T[]] |
[`get${Sing}ById`, (id: string) => T] |
[`get${Plur}ByTitle`, (title: string) => T[]]
>;
@zaverden The more straightforward syntax you're hoping for wouldn't happen until we someday (hopefully) unify mapped type and arbitrary index signatures. See #26797 for more on that.
comment created time in 20 days
issue closedmicrosoft/TypeScript
Recursive conditional types seem to hang experience
https://en.wikipedia.org/wiki/Collatz_conjecture
So the following does not hang TypeScript nightly
type Unary = ReadonlyArray<1>;
type UZero = [];
type UIncr<U extends Unary> = [1, ...U];
type UDecr<U extends Unary> = U extends UIncr<infer U1> ? U1 : never;
type UOne = UIncr<UZero>;
type Collatz<T extends Unary> = T extends UOne ? UOne : HailstoneHelper<T, UZero, T>;
type TimesThreePlusOne<T extends Unary> = UIncr<[...T, ...T, ...T]>;
type HailstoneHelper<Orig extends Unary, HalfAccum extends Unary, Curr extends Unary> =
Curr extends UZero ? HalfAccum :
Curr extends UOne ? Collatz<TimesThreePlusOne<Orig>> :
Collatz<HailstoneHelper<Orig, UIncr<HalfAccum>, UDecr<UDecr<Curr>>>>;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Type instantiation is excessively deep and possibly infinite.(2589)
But introducing a trailing conditional type will cause the following example to seemingly never end:
type Unary = ReadonlyArray<1>;
type UZero = [];
type UIncr<U extends Unary> = [1, ...U];
type UDecr<U extends Unary> = U extends UIncr<infer U1> ? U1 : never;
type UOne = UIncr<UZero>;
type Collatz<T extends Unary> = T extends UOne ? UOne : HailstoneHelper<T, UZero, T>;
type TimesThreePlusOne<T extends Unary> = UIncr<[...T, ...T, ...T]>;
type HailstoneHelper<Orig extends Unary, HalfAccum extends Unary, Curr extends Unary> =
Curr extends UZero ? HalfAccum :
Curr extends UOne ? Collatz<TimesThreePlusOne<Orig>> :
Curr extends [any, any, ...any[]] ? Collatz<HailstoneHelper<Orig, UIncr<HalfAccum>, UDecr<UDecr<Curr>>> :
never;
closed time in 20 days
DanielRosenwasserissue commentmicrosoft/TypeScript
Recursive conditional types seem to hang experience
Marking this as working as intended. It is indeed possible to write types that take a very long time to resolve and/or relate.
comment created time in 20 days
issue closedmicrosoft/TypeScript
Type error emitted for valid type index lookups in variadic tuple types
TypeScript Version: 4.0.0-beta
<!-- Search terms you tried before logging this (so others can find this issue more easily) --> Search Terms: cannot be used to index type tuple partial generic template variadic
Code
type WithOneMore<T extends unknown[]> = [...T, ''];
type LengthPlusOne<T extends unknown[]> = WithOneMore<T>['length'];
type TestNowFour = LengthPlusOne<['a', 'b', 'c']>;
Expected behavior:
There should be no type checker errors. TestNowFour is equal to the literal 4.
Actual behavior:
The following error is emitted for WithOneMore<T>['length']:
ts(2536): Type '"length"' cannot be used to index type '[...T, ""]'.
Interestingly, TestNowFour is computed to be equal to the literal 4 regardless of the error.
Playground Link: Playground Link
Related Issues: Nothing particularly close. #5453 tracked the variadic kinds proposal and #39094 implemented them. I am keenly looking at what's coming out of the recursive conditional types mentioned in #40006 though...
closed time in 20 days
JoshuaKGoldbergissue commentmicrosoft/TypeScript
Type error emitted for valid type index lookups in variadic tuple types
No longer reproduces on 4.0.2 or master. I believe this was fixed before we shipped 4.0.
comment created time in 20 days
push eventmicrosoft/TypeScript
commit sha cea1cfb82edde53d9d1b3280a193fc1bb549e431
Consistently error when rest element isn't last in tuple type (#40254) * Consistently error when rest element isn't last in tuple type * Add regression test * Accept new baselines * Stricter circular recursion check in type inference * Revert "Stricter circular recursion check in type inference" This reverts commit 80e6df6230ffc4f2416e23759c0749aa1cebf5d1. * Revert "Accept new baselines" This reverts commit 355706dadc8d2eb30f283e927d52d13736f6dd65. * Accept new baselines
push time in 20 days
PR merged microsoft/TypeScript
Fixes #40235.
pr closed time in 20 days
issue closedmicrosoft/TypeScript
<!-- 🚨 STOP 🚨 STOP 🚨 STOP 🚨
Half of all issues filed here are duplicates, answered in the FAQ, or not appropriate for the bug tracker. Even if you think you've found a bug, please read the FAQ first, especially the Common "Bugs" That Aren't Bugs section!
Please help us by doing the following steps before logging an issue:
- Search: https://github.com/Microsoft/TypeScript/search?type=Issues
- Read the FAQ: https://github.com/Microsoft/TypeScript/wiki/FAQ
Please fill in the entire template below. -->
<!--
Please try to reproduce the issue with the latest published version. It may have already been fixed.
For npm: typescript@next
This is also the 'Nightly' version in the playground: http://www.typescriptlang.org/play/?ts=Nightly
-->
TypeScript Version: 4.0.2
<!-- Search terms you tried before logging this (so others can find this issue more easily) --> Search Terms: unbounded
Code
type Strings = [string, string];
type Numbers = number[];
type Unbounded = [...Strings, ...Numbers, boolean];
// ^?
const data: Unbounded = ['a', 'b', false, false]; // <-- No error?
console.log(data);
Expected behavior:
The above Unbounded type should allow only the last element in the tuple as boolean, other elements in range [2, -2] if available should be numbers only.
Actual behavior:
[...number[], boolean] is now handled as <number | boolean>[]
Playground Link: <!-- A link to a TypeScript Playground "Share" link which demonstrates this behavior --> https://www.typescriptlang.org/play?#code/C4TwDgpgBAysBOBLAdgcwM5QLxQNroRVQBooCk0BdAbgChRIoA5AVwFsAjCeTHZdrvFw1a9cNACqyDgHsWyACYQF2PADoNcChlIa1rTt3SlZMgDYQAhshEB6W1EcA9APyiAxjOQEoCy8EsALigpWXklFRxcAHJLaNJojnioADNLM3QIUjSMiBFPb3MINTMZVAAKPwCASmogA
Related Issues: <!-- Did you find other bugs that looked similar? --> No.
closed time in 20 days
roylingpush eventmicrosoft/TypeScript
commit sha 930b81cc45f11f810f36d22fbf9012bee2eb4508
Set stackTraceLimit to 0 in fileSystemEntryExists The exception thrown by Node.js's fs.statSync function contains a stack trace that can be expensive to compute. Since this exception isn't used by fileSystemEntryExists, we can safely set Error.stackTraceLimit to 0 without a change in behavior. --- A significant performance improvement was noticed with this change while profiling tsserver on packages within a proprietary monorepo. Specifically, my team saw high self time percentages for Node.js's uvException and handleErrorFromBinding internal functions. These functions are executed within fs.statSync when it fails to find the given path. https://user-images.githubusercontent.com/906558/90183227-220cb800-dd81-11ea-8d61-f41f89481f46.png fs.statSync: https://github.com/nodejs/node/blob/v14.4.0/lib/fs.js#L1030-L1037 handleErrorFromBinding: https://github.com/nodejs/node/blob/v14.4.0/lib/internal/fs/utils.js#L254-L269 uvException: https://github.com/nodejs/node/blob/v14.4.0/lib/internal/errors.js#L390-L443 ## Measurements After adding Error.stackTraceLimit = 0, we saw: - For a large configured project with 12,565 files, tsserver reached the projectLoadingFinish event 48.78% faster. (~46.786s vs ~31.447s) - For a medium project with 7,064 files, tsserver was 25.75% faster. (~20.897s vs ~16.618s) - For a small project with 796 files, tsserver was only a negligible 3.00% faster. (~3.545s vs ~3.442) Measurements were taken on macOS 10.15.6, Node.js 14.4.0, and a recent master commit of TypeScript (610fa28d). The average of 3 runs before and after this change were taken. I would normally include .cpuprofile and isolate-*-*-*.log files, but can't post them publicly in this case. If there's any other summaries the TypeScript team would be curious about I can report them. ## fs.statSync Misses Within our monorepo, the fs.statSync misses were mostly searches for alternative file extensions of module imports. - For node_modules imports, a lot of .ts/.tsx lookups failed until the .d.ts file was found. - Within projects with a lot of JSX files, .ts files were looked for before finding the .tsx version. - In the medium scale project mentioned above, a total of 38,515 non-existent files were queried during createProgram.
commit sha 9f3af6792943a2a5a6987fe8ca9e1326555f8d7c
fix(10019): allow renaming labels (#40064)
commit sha 9bf6b7bf53b015b278ccb76b4d6b13c43ef21ba5
LEGO: check in for master to temporary branch.
commit sha a2d20a2f4d18443010e907394a58760b1b1940c2
LEGO: Merge pull request 40108 LEGO: Merge pull request 40108
commit sha c191f10ed6cb9d6ab648b63ef88d46881b543e4e
LEGO: check in for master to temporary branch.
commit sha 24832e8100905c4eb9c0d2780b10e8f30b719c3c
LEGO: Merge pull request 40112 LEGO: Merge pull request 40112
commit sha dbab46c363fba4ee26a74875de3a2e35925e2de7
The falsy part of any/unknown is any/unknown (#39529)
commit sha 6fea7ff5364bbcb5f4da82e5dbf903e9355a97cf
Add unit tests for VersionRange (#40114) * Add unit tests for VersionRange Make it easier to understand the intended semantics next time I have to read this code. * I miss prettier
commit sha 56a2e349913c2d7a4beab45556e48af0f805a943
Ping @sandersn on new user baseline commits (#40117) * Ping @sandersn on new user baseline commits You asked for this~ * Update whitespace/comment
commit sha 5ff1b75aff3e57b6d8b8ff6cf9791eec2c881b39
Merge pull request #40043 from gluxon/uvException-hotspot Set stackTraceLimit to 0 in fileSystemEntryExists
commit sha a9277b7e0291fb97c3c25fe0f14c29d42f91a8e6
LEGO: check in for master to temporary branch.
commit sha 6a622a11c9bd8773d25076ad7edc39c5c64e7711
LEGO: Merge pull request 40119 LEGO: Merge pull request 40119
commit sha 1e84ffc70313aae70c1cee9ce928a9fff022cabb
Optimize source mapping into external source map sources (#40055)
commit sha f27a11d0dff62e236461bf4410f267d5fadd34d5
LEGO: check in for master to temporary branch.
commit sha c51aacac445f0607eeb2dd0654506ba8161a95ec
LEGO: Merge pull request 40127 LEGO: Merge pull request 40127
commit sha a0d457e14cc3c8e1467d764b5155d5428725075a
Add missing properties to stdlib (#38678)
commit sha 31f495749452c7f3046ea3d621282f72312a7a73
Revert "Optimize source mapping into external source map sources (#40055)" (#40126) This reverts commit 1e84ffc70313aae70c1cee9ce928a9fff022cabb.
commit sha 44d2350e5fcf007fe8c87375a5aaa4e34ee0fb5f
Fix tuple name homogeneity check (#40118)
commit sha 55ca5e91b9abe83a3ba47e34c06635b51376f9fe
Fixes crash on chained property access on require (#40135) From the user tests: ```js const x = require('y').z.ka ``` would cause the crash because I forgot to call getLeftMmostPropertyAccessExpression in one place. Note that this doesn't fix the alias, it just stops the crash.
commit sha 2f2b679436082a17596bf6c0eef7bddf2e308260
Optimize external source maps without full cache (#40130)
push time in 20 days
pull request commentmicrosoft/TypeScript
Template literal types and mapped type 'as' clauses
@rauschma @aminpaks Terminology updated to template literal type.
comment created time in 21 days
push eventmicrosoft/TypeScript
commit sha b2518c6300036c81d79755ffe1e41b38a64e6752
Rename from TemplateType to TemplateLiteralType
commit sha 2d70ca2e3273c3eb5580102f26d008e128a0e6dc
Accept new API baselines
commit sha 096d0aefeafb64aadc714fc811ff26fa4d611374
Add tests
commit sha 1488f35fe73feb7341db3e32a299510837bf22bf
Accept new baselines
push time in 21 days
pull request commentmicrosoft/TypeScript
Template string types and mapped type 'as' clauses
If a mapped type has an as clause, is there a reason to continue to require that the type on the right of the in operator needs to be assignable to string | number | symbol?
@ethanresnick You're right, no reason to constrain the in T type when an as N clause is present. Fixed by my latest commit.
Also, in those mapped types, why does N need to be assignable to string (per your OP, as opposed to string | number | symbol)?
The OP was just wrong here, it's actually string | number | symbol.
comment created time in 22 days