My Code:
const WEEKDAYS_SHORT: string[] = ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam']
the error message comes from TypeScript (3.0) compiler:
TS2322: Type 'string[]' is not assignable to type '[string, string, string, string, string, string, string]'. Property '0' is missing in type 'string[]'.
if I change the string[]
to ReadonlyArray<string>
, then the error message becomes:
TS2322: Type 'ReadonlyArray' is not assignable to type '[string, string, string, string, string, string, string]'. Property '0' is missing in type 'ReadonlyArray'.
my tsconfig.json:
{
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es6", "dom"],
"module": "es6",
"moduleResolution": "node",
"sourceMap": true,
"target": "es5",
"jsx": "react",
"strict": true
},
"exclude": [
"**/*.spec.ts",
"node_modules",
"vendor",
"public"
],
"compileOnSave": false
}
how can I define a readonly array in TypeScript?
Arrays are Not Constants The keyword const is a little misleading. It does NOT define a constant array. It defines a constant reference to an array. Because of this, we can still change the elements of a constant array.
You can also use array constants, values you just enter in the formula bar inside braces: {}. Then you can name your constant so it's easier to use again. You can use constants in your array formulas or by themselves. The constant is inside the braces ({)}, and yes, you really do type those braces manually.
The property of a const object can be change but it cannot be change to reference to the new object. The values inside the const array can be change, it can add new items to const arrays but it cannot reference to a new array.
Assert your array declaration as const
;
const readonlyArray = [1, 2, 3] as const;
Additionally, accessing the element type of a readonly
array is trivial:
type Element = typeof readonlyArray[number]` // 1 | 2 | 3
as const
assertions work on any declarations, including objects and deeply nested data structures. You can even assert an expression as const
. For instance, if the value 1
is inferred as a number
, but you want to supply the number literal type, simply assert it 1 as const
.
The feature was introduced in TypeScript 3.4
. You can also reference the docs.
Bear in that a readonly
or const
array is often called a tuple (as is the case in Python - reference). Tuples can have elements of the same type or elements of entirely different types. Notice, that in the above example the Element
type was not inferred as number
but as a union of number literals. This is possible because the elements of the tuple are never going to change. It is practical to infer the narrowest possible type. You can, for example, use the number literal type 1
anywhere where a number
is required, but you cannot use the number
type where the number literal type 1
is required.
A tuple of two elements is often called a pair and may be represented as a product. Although the product of [number, string]
is not a number, you can still multiply them together. Because both string
and number
are infinitely large themselves, so is their product type. Consider simpler example of [1 | 2 | 3, 'a' | 'b' | 'c']
, which is equal to:
[1, 'a']
| [1, 'b']
| [1, 'c']
| [2, 'a']
| [2, 'b']
| [2, 'c']
| [3, 'a']
| [3, 'b']
| [3, 'c']
Further reading:
After debugging, I found it is not TypeScript compiler problem, it is because I used a third-party component call DayPicker:
<DayPicker
onDayClick={this.handleDayClick}
selectedDays={posts.day}
months={MONTHS}
weekdaysShort={WEEKDAYS_SHORT}
firstDayOfWeek={1}/>
the type of the prop weekdaysShort
is not string[]
, but [string, string, string, string, string, string, string]
weekdaysShort?: [string, string, string, string, string, string, string];
so TS compile says string[]
doesn't match [string, string, string, string, string, string, string]
.
finally, I just changed the type from string[]
to any
to avoid this anoy error message, of course, we can change to [string, string, string, string, string, string, string]
as well (too long).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With