Repository navigation
Type checking does not works for indexable type with number keys OR string keys #34611
Description
Try with newest TypeScript
TypeScript Version: 3.7.0-dev.20191018
Result: has not been fixed.
Search Terms:
typescript indexable type string keys or number keys
Code
enum PROPERTIES_TYPES {
NUMBER = "NUMBER",
STRING = "STRING"
// ETC.
}
interface IStringPropertySpecification {
type: PROPERTIES_TYPES.STRING;
required: boolean;
nullable?: boolean;
newName?: string;
emptyStringIsAllowed: boolean;
allowedValues?: Array<string>;
invalidValueSubstitution: string;
defaultValue?: string;
}
interface IObjectDataSpecification__StringKeys {
nameForLogging: string;
properties: {
[propertyName: string]: IStringPropertySpecification;
};
}
interface IObjectDataSpecification__NumberKeys {
nameForLogging: string;
properties: {
[propertyName: number]: IStringPropertySpecification;
};
}
type ObjectDataSpecification = IObjectDataSpecification__StringKeys | IObjectDataSpecification__NumberKeys;
const dataSpecification: ObjectDataSpecification = {
nameForLogging: "Test",
properties: {
foo: "asdfsadffsd" // Valid!!! No type errors!
}
};Expected behavior:
The error occurrence. I suppose, it must be:
TS2322 Type 'string' is not assignable to type ObjectDataSpecification
Actual behavior:
TypeScript ignores this error. However, my PhpStorm knows right autocompletes:
Playground Link: https://jsfiddle.net/pfg1mq96/
Why I need so strange type as ObjectDataSpecification?
The ObjectDataSpecification has been created for external data validation. It's known in advance, which type external data SHOULD be, but it's unknown in advance, which data ACTUALLY WILL BE. If data satisfies ObjectDataSpecification, it will be cast as below:
const validData: IValidData = rawData as IValidData;
In above case, IValidData will be:
interface IValidData { foo: string; }
Normally, programmers should not create type like:
type ConfusingType {
1: string;
foo: number;
}
However I can't hope for high-quality API in the team work, The API team could define ANYTHING includes strange structure like above ConfusingType . Even it happens, I must to describe the ConfusingType with my ObjectDataSpecification. It will be:
const dataSpecification: ObjectDataSpecification = {
nameForLogging: "ConfusingType ",
properties: {
1: {
type: PROPERTIES_TYPES.STRING,
required: true,
emptyStringIsAllowed: false,
invalidValueSubstitution: "---"
},
foo: {
type: PROPERTIES_TYPES.NUMBER,
required: true,
numberType: NUMBER_TYPES.NATURAL_NUMBER,
invalidValueSubstitution: 1
}
}
};
Then, my library validates external data according to dataSpecification.

Activity
[-]Type checking does not works for indexable type with number OR string keys[/-][+]Type checking does not works for indexable type with number key OR string keys[/+][-]Type checking does not works for indexable type with number key OR string keys[/-][+]Type checking does not works for indexable type with number keys OR string keys[/+]dragomirtitian commentedon Oct 21, 2019
A simpler repro, that has less going on:
Play
selipso commentedon Oct 25, 2019
Is it just me or has the OR type just become f*cking broken in TypeScript 3? I don't know which version it started happening, but TypeScript 2 just felt like the best balance in providing helpful type checking without being overly anal.
For example, error messages like these have caused me to constantly rage at Typescript because of clearly not following what "OR" is supposed to mean.
This is clearly TypeScript's fault because one of the possible return types is clearly listed as a Promise, and yet it doesn't allow me to use
.then()because it picks the other type to be anal about. It treats OR as AND.RyanCavanaugh commentedon Oct 30, 2019
Yatit Thakker (@selipso) please file a separate bug if you think you've found a bug
RyanCavanaugh commentedon Oct 30, 2019
Anders Hejlsberg (@ahejlsberg) I think you have a PR in progress for this?
ahejlsberg commentedon Nov 5, 2019
Even simpler repros:
Both assignments above should be errors, but neither are. The issue is that our excess property logic doesn't properly handle union types with constituents that have index signatures.
TokugawaTakeshi commentedon Nov 16, 2019
Anders Hejlsberg (@ahejlsberg) Thank you for the fixing!
In which version this fix will be available?