8000 Merge remote-tracking branch 'Microsoft/master' · DINKIN/TypeScript@9e0949b · GitHub
[go: up one dir, main page]

Skip to content

Commit 9e0949b

Browse files
committed
Merge remote-tracking branch 'Microsoft/master'
2 parents 90fb901 + 690b87c commit 9e0949b

File tree

82 files changed

+948
-686
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+948
-686
lines changed

src/compiler/checker.ts

Lines changed: 51 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -3119,7 +3119,7 @@ namespace ts {
31193119
}
31203120

31213121
function resolveTupleTypeMembers(type: TupleType) {
3122-
let arrayType = resolveStructuredTypeMembers(createArrayType(getUnionType(type.elementTypes, /*noDeduplication*/ true)));
3122+
let arrayType = resolveStructuredTypeMembers(createArrayType(getUnionType(type.elementTypes, /*noSubtypeReduction*/ true)));
31233123
let members = createTupleTypeMemberSymbols(type.elementTypes);
31243124
addInheritedMembers(members, arrayType.properties);
31253125
setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexType, arrayType.numberIndexType);
@@ -3451,29 +3451,6 @@ namespace ts {
34513451
return undefined;
34523452
}
34533453

3454-
// Check if a property with the given name is known anywhere in the given type. In an object
3455-
// type, a property is considered known if the object type is empty, if it has any index
3456-
// signatures, or if the property is actually declared in the type. In a union or intersection
3457-
// type, a property is considered known if it is known in any constituent type.
3458-
function isKnownProperty(type: Type, name: string): boolean {
3459-
if (type.flags & TypeFlags.ObjectType && type !== globalObjectType) {
3460-
const resolved = resolveStructuredTypeMembers(type);
3461-
return !!(resolved.properties.length === 0 ||
3462-
resolved.stringIndexType ||
3463-
resolved.numberIndexType ||
3464-
getPropertyOfType(type, name));
3465-
}
3466-
if (type.flags & TypeFlags.UnionOrIntersection) {
3467-
for (let t of (<UnionOrIntersectionType>type).types) {
3468-
if (isKnownProperty(t, name)) {
3469-
return true;
3470-
}
3471-
}
3472-
return false;
3473-
}
3474-
return true;
3475-
}
3476-
34773454
function getSignaturesOfStructuredType(type: Type, kind: SignatureKind): Signature[] {
34783455
if (type.flags & TypeFlags.StructuredType) {
34793456
let resolved = resolveStructuredTypeMembers(<ObjectType>type);
@@ -4103,73 +4080,20 @@ namespace ts {
41034080
}
41044081
}
41054082

4106-
function isObjectLiteralTypeDuplicateOf(source: ObjectType, target: ObjectType): boolean {
4107-
let sourceProperties = getPropertiesOfObjectType(source);
4108-
let targetProperties = getPropertiesOfObjectType(target);
4109-
if (sourceProperties.length !== targetProperties.length) {
4110-
return false;
4111-
}
4112-
for (let sourceProp of sourceProperties) {
4113-
let targetProp = getPropertyOfObjectType(target, sourceProp.name);
4114-
if (!targetProp ||
4115-
getDeclarationFlagsFromSymbol(targetProp) & (NodeFlags.Private | NodeFlags.Protected) ||
4116-
!isTypeDuplicateOf(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp))) {
4117-
return false;
4118-
}
4119-
}
4120-
return true;
4121-
}
4122-
4123-
function isTupleTypeDuplicateOf(source: TupleType, target: TupleType): boolean {
4124-
let sourceTypes = source.elementTypes;
4125-
let targetTypes = target.elementTypes;
4126-
if (sourceTypes.length !== targetTypes.length) {
4127-
return false;
4128-
}
4129-
for (var i = 0; i < sourceTypes.length; i++) {
4130-
if (!isTypeDuplicateOf(sourceTypes[i], targetTypes[i])) {
4131-
return false;
4132-
}
4133-
}
4134-
return true;
4135-
}
4136-
4137-
// Returns true if the source type is a duplicate of the target type. A source type is a duplicate of
4138-
// a target type if the the two are identical, with the exception that the source type may have null or
4139-
// undefined in places where the target type doesn't. This is by design an asymmetric relationship.
4140-
function isTypeDuplicateOf(source: Type, target: Type): boolean {
4141-
if (source === target) {
4142-
return true;
4143-
}
4144-
if (source.flags & TypeFlags.Undefined || source.flags & TypeFlags.Null && !(target.flags & TypeFlags.Undefined)) {
4145-
return true;
4146-
}
4147-
if (source.flags & TypeFlags.ObjectLiteral && target.flags & TypeFlags.ObjectType) {
4148-
return isObjectLiteralTypeDuplicateOf(<ObjectType>source, <ObjectType>target);
4149-
}
4150-
if (isArrayType(source) && isArrayType(target)) {
4151-
return isTypeDuplicateOf((<TypeReference>source).typeArguments[0], (<TypeReference>target).typeArguments[0]);
4152-
}
4153-
if (isTupleType(source) && isTupleType(target)) {
4154-
return isTupleTypeDuplicateOf(<TupleType>source, <TupleType>target);
4155-
}
4156-
return isTypeIdenticalTo(source, target);
4157-
}
4158-
4159-
function isTypeDuplicateOfSomeType(candidate: Type, types: Type[]): boolean {
4160-
for (let type of types) {
4161-
if (candidate !== type && isTypeDuplicateOf(candidate, type)) {
4083+
function isSubtypeOfAny(candidate: Type, types: Type[]): boolean {
4084+
for (let i = 0, len = types.length; i < len; i++) {
4085+
if (candidate !== types[i] && isTypeSubtypeOf(candidate, types[i])) {
41624086
return true;
41634087
}
41644088
}
41654089
return false;
41664090
}
41674091

4168-
function removeDuplicateTypes(types: Type[]) {
4092+
function removeSubtypes(types: Type[]) {
41694093
let i = types.length;
41704094
while (i > 0) {
41714095
i--;
4172-
if (isTypeDuplicateOfSomeType(types[i], types)) {
4096+
if (isSubtypeOfAny(types[i], types)) {
41734097
types.splice(i, 1);
41744098
}
41754099
}
@@ -4194,12 +4118,14 @@ namespace ts {
41944118
}
41954119
}
41964120

4197-
// We always deduplicate the constituent type set based on object identity, but we'll also deduplicate
4198-
// based on the structure of the types unless the noDeduplication flag is true, which is the case when
4199-
// creating a union type from a type node and when instantiating a union type. In both of those cases,
4200-
// structural deduplication has to be deferred to properly support recursive union types. For example,
4201-
// a type of the form "type Item = string | (() => Item)" cannot be deduplicated during its declaration.
4202-
function getUnionType(types: Type[], noDeduplication?: boolean): Type {
4121+
// We reduce the constituent type set to only include types that aren't subtypes of other types, unless
4122+
// the noSubtypeReduction flag is specified, in which case we perform a simple deduplication based on
4123+
// object identity. Subtype reduction is possible only when union types are known not to circularly
4124+
// reference themselves (as is the case with union types created by expression constructs such as array
4125+
// literals and the || and ?: operators). Named types can circularly reference themselves and therefore
4126+
// cannot be deduplicated during their declaration. For example, "type Item = string | (() => Item" is
4127+
// a named type that circularly references itself.
4128+
function getUnionType(types: Type[], noSubtypeReduction?: boolean): Type {
42034129
if (types.length === 0) {
42044130
return emptyObjectType;
42054131
}
@@ -4208,12 +4134,12 @@ namespace ts {
42084134
if (containsTypeAny(typeSet)) {
42094135
return anyType;
42104136
}
4211-
if (noDeduplication) {
4137+
if (noSubtypeReduction) {
42124138
removeAllButLast(typeSet, undefinedType);
42134139
removeAllButLast(typeSet, nullType);
42144140
}
42154141
else {
4216-
removeDuplicateTypes(typeSet);
4142+
removeSubtypes(typeSet);
42174143
}
42184144
if (typeSet.length === 1) {
42194145
return typeSet[0];
@@ -4230,7 +4156,7 @@ namespace ts {
42304156
function getTypeFromUnionTypeNode(node: UnionTypeNode): Type {
42314157
let links = getNodeLinks(node);
42324158
if (!links.resolvedType) {
4233-
links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNode), /*noDeduplication*/ true);
4159+
links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNode), /*noSubtypeReduction*/ true);
42344160
}
42354161
return links.resolvedType;
42364162
}
@@ -4526,7 +4452,7 @@ namespace ts {
45264452
return createTupleType(instantiateList((<TupleType>type).elementTypes, mapper, instantiateType));
45274453
}
45284454
if (type.flags & TypeFlags.Union) {
4529-
return getUnionType(instantiateList((<UnionType>type).types, mapper, instantiateType), /*noDeduplication*/ true);
4455+
return getUnionType(instantiateList((<UnionType>type).types, mapper, instantiateType), /*noSubtypeReduction*/ true);
45304456
}
45314457
if (type.flags & TypeFlags.Intersection) {
45324458
return getIntersectionType(instantiateList((<IntersectionType>type).types, mapper, instantiateType));
@@ -4622,7 +4548,7 @@ namespace ts {
46224548
* @param target The right-hand-side of the relation.
46234549
* @param relation The relation considered. One of 'identityRelation', 'assignableRelation', or 'subTypeRelation'.
46244550
* Used as both to determine which checks are performed and as a cache of previously computed results.
4625-
* @param errorNode The node upon which all errors will be reported, if defined.
4551+
* @param errorNode The suggested node upon which all errors will be reported, if defined. This may or may not be the actual node used.
46264552
* @param headMessage If the error chain should be prepended by a head message, then headMessage will be used.
46274553
* @param containingMessageChain A chain of errors to prepend any new errors found.
46284554
*/
@@ -4813,11 +4739,41 @@ namespace ts {
48134739
return Ternary.False;
48144740
}
48154741

4742+
// Check if a property with the given name is known anywhere in the given type. In an object type, a property
4743+
// is considered known if the object type is empty and the check is for assignability, if the object type has
4744+
// index signatures, or if the property is actually declared in the object type. In a union or intersection
4745+
// type, a property is considered known if it is known in any constituent type.
4746+
function isKnownProperty(type: Type, name: string): boolean {
4747+
if (type.flags & TypeFlags.ObjectType) {
4748+
const resolved = resolveStructuredTypeMembers(type);
4749+
if (relation === assignableRelation && (type === globalObjectType || resolved.properties.length === 0) ||
4750+
resolved.stringIndexType || resolved.numberIndexType || getPropertyOfType(type, name)) {
4751+
return true;
4752+
}
4753+
return false;
4754+
}
4755+
if (type.flags & TypeFlags.UnionOrIntersection) {
4756+
for (let t of (<UnionOrIntersectionType>type).types) {
4757+
if (isKnownProperty(t, name)) {
4758+
return true;
4759+
}
4760+
}
4761+
return false;
4762+
}
4763+
return true;
4764+
}
4765+
48164766
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
48174767
for (let prop of getPropertiesOfObjectType(source)) {
48184768
if (!isKnownProperty(target, prop.name)) {
48194769
if (reportErrors) {
4820-
reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(prop), typeToString(target));
4770+
// We know *exactly* where things went wrong when comparing the types.
4771+
// Use this property as the error node as this will be more helpful in
4772+
// reasoning about what went wrong.
4773+
errorNode = prop.valueDeclaration
4774+
reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1,
4775+
symbolToString(prop),
4776+
typeToString(target));
48214777
}
48224778
return true;
48234779
}
@@ -5594,7 +5550,7 @@ namespace ts {
55945550
return getWidenedTypeOfObjectLiteral(type);
55955551
}
55965552
if (type.flags & TypeFlags.Union) {
5597-
return getUnionType(map((<UnionType>type).types, getWidenedType));
5553+
return getUnionType(map((<UnionType>type).types, getWidenedType), /*noSubtypeReduction*/ true);
55985554
}
55995555
if (isArrayType(type)) {
56005556
return createArrayType(getWidenedType((<TypeReference>type).typeArguments[0]));

src/compiler/commandLineParser.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,6 @@ namespace ts {
243243
"node": ModuleResolutionKind.NodeJs,
244244
"classic": ModuleResolutionKind.Classic
245245
},
246-
experimental: true,
247246
description: Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6
248247
}
249248
];

src/lib/intl.d.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ declare module Intl {
8888
timeZoneName?: string;
8989
formatMatcher?: string;
9090
hour12?: boolean;
91+
timeZone?: string;
9192
}
9293

9394
interface ResolvedDateTimeFormatOptions {
@@ -157,17 +158,44 @@ interface Number {
157158

158159
interface Date {
159160
/**
160-
* Converts a date to a string by using the current or specified locale.
161+
* Converts a date and time to a string by using the current or specified locale.
161162
* @param locales An array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.
162163
* @param options An object that contains one or more properties that specify comparison options.
163164
*/
164165
toLocaleString(locales?: string[], options?: Intl.DateTimeFormatOptions): string;
165-
166166
/**
167167
* Converts a date to a string by using the current or specified locale.
168+
* @param locales An array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.
169+
* @param options An object that contains one or more properties that specify comparison options.
170+
*/
171+
toLocaleDateString(locales?: string[], options?: Intl.DateTimeFormatOptions): string;
172+
173+
/**
174+
* Converts a time to a string by using the current or specified locale.
175+
* @param locale Locale tag. If you omit this parameter, the default locale of the JavaScript runtime is used.
176+
* @param options An object that contains one or more properties that specify comparison options.
177+
*/
178+
toLocaleTimeString(locale?: string[], options?: Intl.DateTimeFormatOptions): string;
179+
180+
/**
181+
* Converts a date and time to a string by using the current or specified locale.
168182
* @param locale Locale tag. If you omit this parameter, the default locale of the JavaScript runtime is used.
169183
* @param options An object that contains one or more properties that specify comparison options.
170184
*/
171185
toLocaleString(locale?: string, options?: Intl.DateTimeFormatOptions): string;
186+
187+
/**
188+
* Converts a date to a string by using the current or specified locale.
189+
* @param locale Locale tag. If you omit this parameter, the default locale of the JavaScript runtime is used.
190+
* @param options An object that contains one or more properties that specify comparison options.
191+
*/
192+
toLocaleDateString(locale?: string, options?: Intl.DateTimeFormatOptions): string;
193+
194+
/**
195+
* Converts a time to a string by using the current or specified locale.
196+
* @param locale Locale tag. If you omit this parameter, the default locale of the JavaScript runtime is used.
197+
* @param options An object that contains one or more properties that specify comparison options.
198+
*/
199+
toLocaleTimeString(locale?: string, options?: Intl.DateTimeFormatOptions): string;
172200
}
173201

0 commit comments

Comments
 (0)
0