型の互換性
// 型互換性あり
let fooCompatible: any
let barCompatible: string = "TypeScript"
console.log(typeof fooCompatible)
// > undefined
fooCompatible = barCompatible
console.log(typeof fooCompatible)
// > string
// any型にstring型のデータを代入することでstring型になる
let fooString: string
let barString: string = "string"
fooString = barString
let string: string
let stringLiteral: "fooStringLiteral" = "fooStringLiteral"
string = stringLiteral
let fooNumber: number
let fooNumberLiteral: 1000 = 1000
fooNumber = fooNumberLiteral
// 型互換性なし
let fooIncompatible: string
let barIncompatible: number
// fooIncompatible = barIncompatible
// error TS2454: Variable 'barIncompatible' is used before being assigned.
// interfaceとclassのconstructorでも型互換性が評価される
interface Animal {
age: number
name: string
}
class Person {
constructor(public age: number, public name: string) {}
}
let me: Animal
me = new Person(24, "a")
ジェネリクス
// const echo = (arg: number): number => {
// return arg
// }
// const echo = (arg: string): string => {
// return arg
// }
// 上記を以下のように記述することができる
const echo = <T>(arg: T): T => {
return arg
}
console.log(echo<number>(100))
// > 100
console.log(echo<string>("hello"))
// > hello
console.log(echo<boolean>(false))
// > false
class Mirror<T> {
constructor(public value: T) {}
echo(): T {
return this.value
}
}
console.log(new Mirror<number>(123).echo())
// > 123
console.log(new Mirror<string>("hello, generics!").echo())
// > hello, generics!
console.log(new Mirror<boolean>(true).echo())
// > true
型アサーション
let name: any = "Tanaka"
let length = (name as string).length
// length = "foo"
// > error TS2322: Type 'string' is not assignable to type 'number'.
let name2: any = "Tanaka"
constアサーション
let name = "Tanaka"
name = "Tatsuya"
let nickname = "Tatsuya" as const
nickname = "Tatsuya"
// nickname = "Tatsu"
// > error TS2322: Type '"Tatsu"' is not assignable to type '"Tatsuya"'.
let profile = {
name: "Tanaka",
height: 201
} as const
// let profile: {
// readonly name: "Tanaka";
// readonly height: 201;
// }
// profile.name = "Tanaka"
// error TS2540: Cannot assign to 'name' because it is a read-only property.
// profile.height = 400
// error TS2540: Cannot assign to 'height' because it is a read-only property.
// as const を記述することで別の値を代入することを制限することができる
Nullable
let profile: { name: string, age: number | null } = {
name: "hana",
age: null
}
インデックスシグネチャ
interface Profile {
name: string
underTwenty: boolean,
[index: string]: string | number | boolean
}
// 上記に具体的に記述されているプロパティは初期化する必要がある
let profile: Profile = {
name: "Tanaka",
underTwenty: false
}
profile.name = "Tanaka"
profile.age = 41
profile.nationality = "Japan"