TypeScript 3.4+
TypeScript version 3.4 has introduced so-called **const contexts**, which is a way to declare a tuple type as immutable and get the narrow literal type directly (without the need to call a function like shown below in the 3.0 solution).With this new syntax, we get this nice concise solution:
const furniture = ['chair', 'table', 'lamp'] as const;
type Furniture = typeof furniture[number];
More about the new const contexts is found in this PR as well as in the release notes.
TypeScript 3.0+
With the use of generic rest parameters, there is a way to correctly infer string[] as a literal tuple type and then get the union type of the literals.
It goes like this:
const tuple = <T extends string[]>(...args: T) => args;
const furniture = tuple('chair', 'table', 'lamp');
type Furniture = typeof furniture[number];
More about generic rest parameters
Answer from ggradnig on Stack OverflowTypeScript 3.4+
TypeScript version 3.4 has introduced so-called **const contexts**, which is a way to declare a tuple type as immutable and get the narrow literal type directly (without the need to call a function like shown below in the 3.0 solution).With this new syntax, we get this nice concise solution:
const furniture = ['chair', 'table', 'lamp'] as const;
type Furniture = typeof furniture[number];
More about the new const contexts is found in this PR as well as in the release notes.
TypeScript 3.0+
With the use of generic rest parameters, there is a way to correctly infer string[] as a literal tuple type and then get the union type of the literals.
It goes like this:
const tuple = <T extends string[]>(...args: T) => args;
const furniture = tuple('chair', 'table', 'lamp');
type Furniture = typeof furniture[number];
More about generic rest parameters
This answer is out of date; see @ggradnig's answer.
The best available workaround:
const furnitureObj = { chair: 1, table: 1, lamp: 1 };
type Furniture = keyof typeof furnitureObj;
const furniture = Object.keys(furnitureObj) as Furniture[];
Ideally we could do this:
const furniture = ['chair', 'table', 'lamp'];
type Furniture = typeof furniture[number];
Unfortunately, today furniture is inferred as string[], which means Furniture is now also a string.
We can enforce the typing as a literal with a manual annotation, but it brings back the duplication:
const furniture = ["chair", "table", "lamp"] as ["chair", "table", "lamp"];
type Furniture = typeof furniture[number];
TypeScript issue #10195 tracks the ability to hint to TypeScript that the list should be inferred as a static tuple and not string[], so maybe in the future this will be possible.
You can in the interface specify the type as string or array if you want to.
skills: string|string[];
EDIT
As mentioned in the comments, you might have to cast your variable to do certain operations only available to the specific type:
// Convert from string to string[]
this.candidate.skills = (<string>this.candidate.skills).split(', ');
The interface that i implement:
export class Candidate {
id: number;
name: string;
skills: string|string[]; }
In the component i try to upload my data through a service. The code in the component.ts:
import { Component, OnInit } from '@angular/core';
import { CandidatesService } from '../candidates.service';
import { Validators } from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import { Candidate } from '../candidate';
@Component({
selector: 'app-candidates-adding',
templateUrl: './candidates-adding.component.html',
styleUrls: ['./candidates-adding.component.css']
})
export class CandidatesAddingComponent implements OnInit {
candidate: Candidate = new Candidate();
constructor(private candidatesService: CandidatesService) { }
ngOnInit() {
}
saveCandidate(): void {
if(this.candidate.skills.indexOf(', ') >= 0) {
this.candidate.skills = this.candidate.skills.split(', ');
}
this.candidatesService.addCandidate(this.candidate).subscribe();
}
}
And in the template:
<input [(ngModel)]="candidate.name" placeholder="name" minlength="4">
<input [(ngModel)]="candidate.skills" placeholder="name" minlength="1">
<button (click)="saveCandidate()">Adauga candidat</button>
The method array.toString() actually calls array.join() which result in a string concatenated by commas. ref
var array = ['a','b','c','d','e','f'];
document.write(array.toString()); // "a,b,c,d,e,f"
Also, you can implicitly call Array.toString() by making javascript coerce the Array to an string, like:
//will implicitly call array.toString()
str = ""+array;
str = `${array}`;
Array.prototype.join()
The join() method joins all elements of an array into a string.
Arguments:
It accepts a separator as argument, but the default is already a comma ,
str = arr.join([separator = ','])
Examples:
var array = ['A', 'B', 'C'];
var myVar1 = array.join(); // 'A,B,C'
var myVar2 = array.join(', '); // 'A, B, C'
var myVar3 = array.join(' + '); // 'A + B + C'
var myVar4 = array.join(''); // 'ABC'
Note:
If any element of the array is undefined or null , it is treated as an empty string.
Browser support:
It is available pretty much everywhere today, since IE 5.5 (1999~2000).
References
- ECMA Specification
- Mozilla
- MSDN
Use the join method from the Array type.
a.value = [a, b, c, d, e, f];
var stringValueYouWant = a.join();
The join method will return a string that is the concatenation of all the array elements. It will use the first parameter you pass as a separator - if you don't use one, it will use the default separator, which is the comma.