はじめに
- コードの動作確認
-
TypeScript
ちょっとしたコードの動作確認には TypeScript Playground が便利。
コードを書いてRun
ボタンで実行できる。TypeScriptの環境を作るのは結構めんどくさいので重宝する。 -
Python
Trinket CodePlayground などがあるが、適当な.py
ファイル作って実行すればいいと思う。
-
プリミティブ型の変数定義
-
Python
Pythonには var, let, const のような使い分けはなく、全てTypeScriptのletと同じ。 -
TypeScript
TypeScriptの変数定義には var, let, const の3種類ある。
可能な限り const を使う。var と let はどちらも再代入可能な変数を定義するが、
var は古い書き方なので使わない方が良い。全て let でOK。const は定数を定義する。
const でもオブジェクト型であれば要素の変更はできる。
Python
s: str = 'string'
i: int = 0
f: float = 0.0
b: bool = True
# 再代入
s = s + 'xxx' # or s += 'xxx'
i = i + 100 # or i += 100
f = f + 100.0 # or f += 100.0
b = not b
print(s) # 'stringxxx'
print(i) # 100
print(f) # 100.0
print(b) # False
TypeScript
let
let s: string = 'string'
let i: number = 0 // TypeScriptの型に integer はない。
let f: number = 0.0 // TypeScriptの型に float はない。
let b: boolean = true
// 再代入
s = s + 'xxx' // or s += 'xxx'
i = i + 100 // or i += 100
f = f + 100.0 // or f += 100.0
b = !b
console.log(s) // "stringxxx"
console.log(i) // 100
console.log(f) // 100
console.log(b) // false
const
const s: string = 'string'
const i: number = 0
const f: number = 0.0
const b: boolean = true
// 再代入は全て不可(エラー)
s = s + 'xxx' // or s += 'xxx'
i = i + 100 // or i += 100
f = f + 100.0 // or f += 100.0
b = !b
オブジェクト型の変数定義(配列)
Python
a: [str, int, float, bool] = ['string', 0, 0.0, True]
# 要素の変更
a[0] = a[0] + 'xxx' # or a[0] += 'xxx'
a[1] = a[1] + 100 # or a[1] += 100
a[2] = a[2] + 100.0 # or a[2] += 100.0
a[3] = not a[3]
print(a[0]) # 'stringxxx'
print(a[1]) # 100
print(a[2]) # 100.0
print(a[3]) # False
# 再代入
a = ['str', 9, 9.9, False]
print(a) # ['str', 9, 9.9, False]
TypeScript
let
let a: [string, number, number, boolean] = ['string', 0, 0.0, true]
// 要素の変更
a[0] = a[0] + 'xxx' // or a[0] += 'xxx'
a[1] = a[1] + 100 // or a[1] += 100
a[2] = a[2] + 100.0 // or a[2] += 100.0
a[3] = !a[3]
console.log(a[0]) // 'stringxxx'
console.log(a[1]) // 100
console.log(a[2]) // 100.0
console.log(a[3]) // false
// 再代入
a = ['str', 9, 9.9, false]
console.log(a) // ['str', 9, 9.9, false]
const
const a: [string, number, number, boolean] = ['string', 0, 0.0, true]
// 要素の変更は可能( a への再代入ではないため)
a[0] = a[0] + 'xxx' // or a[0] += 'xxx'
a[1] = a[1] + 100 // or a[1] += 100
a[2] = a[2] + 100.0 // or a[2] += 100.0
a[3] = !a[3]
// 再代入は不可(エラー)
a = ['str', 9, 9.9, false]
オブジェクト型の変数定義(辞書 or オブジェクト)
Python
from typing import TypedDict
class Dic(TypedDict):
s: str
i: int
f: float
b: bool
dic: Dic = {
's': 'string',
'i': 0,
'f': 0.0,
'b': True,
}
# 要素の変更
dic['s'] = dic['s'] + 'xxx' # or dic['s'] += 'xxx'
dic['i'] = dic['i'] + 100 # or dic['i'] += 100
dic['f'] = dic['f'] + 100.0 # or dic['f'] += 100.0
dic['b'] = not dic['b']
print(dic['s']) # 'stringxxx'
print(dic['i']) # 100
print(dic['f']) # 100.0
print(dic['b']) # False
# 再代入
dic = {
's': 'str',
'i': 9,
'f': 9.9,
'b': False,
}
print(dic) # {'s': 'str', 'i': 9, 'f': 9.9, 'b': False}
TypeScript
let
interface Obj {
s: string
i: number
f: number
b: boolean
}
let obj: Obj = {
s: 'string',
i: 0,
f: 0.0,
b: true,
}
// 要素の変更
obj.s = obj.s + 'xxx' // or obj.s += 'xxx'
obj.i = obj.i + 100 // or obj.i += 100
obj.f = obj.f + 100.0 // or obj.f += 100.0
obj.b = !obj.b
console.log(obj.s) // 'stringxxx'
console.log(obj.i) // 100
console.log(obj.f) // 100
console.log(obj.b) // false
// 再代入
obj = {
s: 'str',
i: 9,
f: 9.9,
b: false,
}
console.log(obj) // { 's': 'str', 'i': 9, 'f': 9.9, 'b': false }
const
interface Obj {
s: string
i: number
f: number
b: boolean
}
const obj: Obj = {
s: 'string',
i: 0,
f: 0.0,
b: true,
}
// 要素の変更は可能( obj への再代入ではないため)
obj.s = obj.s + 'xxx' // or obj.s += 'xxx'
obj.i = obj.i + 100 // or obj.i += 100
obj.f = obj.f + 100.0 // or obj.f += 100.0
obj.b = !obj.b
// 再代入は不可(エラー)
obj = {
s: 'str',
i: 9,
f: 9.9,
b: false,
}
「const=定数 なのに変更できるってどういうこと?」ってなりそう。
Pythonだけやってた私は結構混乱しましたが、型エラーで悩んでるうちに理解できました。
とりあえずオブジェクト型は const で定義してみましょう。
オブジェクト型を再代入しなければならない状況はあまりありません。
アトリビュートの参照についての補足
Python
dic['key']
で参照する
my_dict = {'key': 'value'}
# この書き方はできない
my_dict.key # 例外 AttributeError: 'dict' object has no attribute 'key'.
my_dict['key'] # 'value'
my_dict['wrong_key'] # 例外 KeyError: 'wrong_key'
# .get()を使うことで例外を避けることができる
my_dict.get('key') # 'value'
my_dict.get('wrong_key') # None
# .get()の第2引数を渡すことでキーがなかった場合のデフォルト値を設定できる
my_dict.get('wrong_key', 'default_value') # default_value
TypeScript
obj.key
, obj['key']
どちらでも参照できる。
Pythonと異なり、存在しないキーを参照しようとしても例外にはならない。
const myObj = { key: 'value' }
// どちらでもちゃんと 'value' を参照できる
myObj.key // こっちの方が短く書けて良い
myObj['key'] // キー名に日本語が含まれる場合などはこちらを使う必要がある
myObj.wrongKey // undefined
myObj['wrong_key'] // undefined
// ? を付けることで型エラーを回避できることも
myObj?.wrongKey // undefined
特殊な型
Pythonの None とTypeScriptの null は同じと考えていい。
TypeScriptには undefined や Symbol があるが、Symbol を使用する機会はかなり少ない。
まだ値が代入されていない変数は undefined 型となる。
let x
console.log(x) // undefined
Pythonで同じことをしようとすると例外になる。
print(x)
Traceback (most recent call last):
File "C:\Program Files\Python310\lib\code.py", line 90, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
NameError: name 'x' is not defined
関数の定義
Python
from typing import TypedDict
class Dic(TypedDict):
k1: str
k2: int
k3: float
k4: bool
def my_func(s: str, i: int, f: float, b: bool) -> Dic:
return {'k1': s, 'k2': i, 'k3': f, 'k4': b}
# デフォルト値ありの関数
def my_func_with_default(s: str = '', i: int = 0, f: float = 0.0, b: bool = False) -> Dic:
return {'k1': s, 'k2': i, 'k3': f, 'k4': b}
if __name__ == '__main__':
x = my_func('string', 0, 0.0, True)
print(x) # {'k1': 'string', 'k2': 0, 'k3': 0.0, 'k4': True}
# 全てデフォルト値
y = my_func_with_default()
print(y) # {'k1': '', 'k2': 0, 'k3': 0.0, 'k4': False}
# 引数を1つだけ指定
z = my_func_with_default('custom string')
print(z) # {'k1': 'custom string', 'k2': 0, 'k3': 0.0, 'k4': False}
TypeScript
interface Obj {
k1: string
k2: number
k3: number
k4: boolean
}
function myFunc(s: string, i: number, f: number, b: boolean): Obj {
return { k1: s, k2: i, k3: f, k4: b }
}
// デフォルト値ありの関数
function myFuncWithDefault(s: string = '', i: number = 0, f: number = 0.0, b: boolean = false): Obj {
return { k1: s, k2: i, k3: f, k4: b }
}
const x = myFunc('string', 0, 0.0, true)
console.log(x) // {"k1": "string", "k2": 0, "k3": 0, "k4": true}
// 全てデフォルト値
const y = myFuncWithDefault()
console.log(y) // {"k1": "", "k2": 0, "k3": 0, "k4": true}
// 引数を1つだけ指定
const z = myFuncWithDefault('custom string')
console.log(z) // {"k1": "custom string", "k2": 0, "k3": 0, "k4": false}
TypeScriptのアロー関数
TypeScriptの関数定義方法にはいろんな書き方があり、結構混乱します。
以下の3つの関数は全て同じ動作をします。
厳密には通常の関数とアロー関数ではthis(Pythonのself)の扱いが異なります
// 通常の関数
function myFunc(x: string): string {
return x
}
// アロー関数
const myArrowFunc = (x: string): string => {
return x
}
// アロー関数定義 + return の省略
const myArrowFunc2 = (x: string): string => x
myFunc('aaa')
myArrowFunc('bbb')
myArrowFunc2('ccc')
クラスの定義
Python
TypeScript
文字列の操作
Python
TypeScript
数値の操作
Python
TypeScript
配列の操作
Python
TypeScript
オブジェクト(辞書)の操作
Python
TypeScript
条件分岐
Python
if x > 5:
print('x > 5')
elif x == 5:
print('x == 5')
elif x != -100:
print('x != -100')
else:
print('else')
# ----------------------------
if 0 < x and x <= 10:
print('0 < x and x <= 10')
# こう書いた方がいい
if 0 < x <= 10:
print('0 < x <= 10')
# ----------------------------
if (0 < x and 0 <= y) or (100 < x and 100 <= y):
print('(0 < x and 0 <= y) or (100 < x and 100 <= y)')
# ----------------------------
# None の判定は is を使う
if x is None:
print('x is None')
if y is not None:
print('y is not None')
TypeScript
==
, !=
は基本使わないこと。
===
, !==
を使う。
// なんとこれはtrueになる
if (0 == '0') {
console.log("0 == '0'")
}
// === で判定すればちゃんと false になる
if (0 === '0') {
console.log("0 === '0'")
}
// ----------------------------
if (x > 5) {
console.log('x > 5')
} else if (x === 5) {
console.log('x === 5')
} else if (x !== -100) {
console.log('x !== -100')
} else {
console.log('else')
}
// ----------------------------
if (0 < x && x <= 10) {
console.log('0 < x && x <= 10')
}
// ----------------------------
if ((0 < x && 0 <= y) || (100 < x && 100 <= y)) {
console.log('(0 < x && 0 <= y) || (100 < x && 100 <= y)')
}
// ----------------------------
// 1行であれば {} を省略できる。(Pythonでもできるが非推奨)
if (true) console.log('true')
else console.log('false')
繰り返し
Python
for ... in ... :
の形。
配列でインデックスも取得したいなら enumerate()
を使う。
辞書なら .keys()
, .values()
, .items()
を使う。
for x in range(10): # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
if x == 3:
continue # for文の先頭に戻る
elif x == 8:
break # for文を抜ける
else:
print(x) # 0 -> 1 -> 2 -> 4 -> 5 -> 6 -> 7
# 配列 -------------
items = ['a', 'b', 'c']
for item in items:
print(item) # 'a' -> 'b' -> 'c'
for i, item in enumerate(items):
print(i) # 0 -> 1 -> 2
print(item) # 'a' -> 'b' -> 'c'
# 辞書 -------------
dic = {
'k1': 'v1',
'k2': 'v2',
'k3': 'v3'
}
for k in dic.keys():
print(k) # 'k1' -> 'k2' -> 'k3'
print(dic[k]) # 'v1' -> 'v2' -> 'v3'
for v in dic.values():
print(v) # 'v1' -> 'v2' -> 'v3'
for k, v in dic.items():
print(k) # 'k1' -> 'k2' -> 'k3'
print(dic[k]) # 'v1' -> 'v2' -> 'v3'
TypeScript
for (... in ...)
とfor (... of ...)
があって少しややこしいが、基本of
だけでいい。
in
は配列であればインデックス(何故かnumberではなくstring)、オブジェクトであればキーを取得する。
of
は配列であれば要素、オブジェクトであれば値を取得する。
配列でインデックスも取得したいなら .entries()
を使う。インデックスのみ取得したいなら .keys()
を使う。
辞書なら Object.keys(...)
, Object.values(...)
, Object.entries(...)
を使う。
for (const x of Array.from(Array(10), (_, i) => i)) { // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
if (x === 3) continue // for文の先頭に戻る
else if (x === 8) break // for文を抜ける
else console.log(x) // 0 -> 1 -> 2 -> 4 -> 5 -> 6 -> 7
}
// 配列 -------------
const items = ["a", "b", "c"]
for (const i in items)
// i は string。何故…
console.log(i) // "0" -> "1" -> "2"
for (const i of items.keys())
console.log(i) // 0 -> 1 -> 2
for (const item of items)
console.log(item) // "a" -> "b" -> "c"
for (const [i, item] of items.entries()) {
console.log(i) // 0 -> 1 -> 2
console.log(item) // "a" -> "b" -> "c"
}
// オブジェクト -------------
const obj: Record<string, string> = {
"k1": "v1",
"k2": "v2",
"k3": "v3"
}
for for (const k of Object.keys(obj)) { // または
console.log(k) // "k1" -> "k2" -> "k3"
console.log(obj[k]) // "v1" -> "v2" -> "v3"
}
for (const v of Object.values(obj))
console.log(v) // "v1" -> "v2" -> "v3"
for (const [k, v] of Object.entries(obj)) {
console.log(k) // "k1" -> "k2" -> "k3"
console.log(v) // "v1" -> "v2" -> "v3"
}
型の判定
Python
TypeScript
型の変換(キャスト)
Python
TypeScript
例外処理
Python
TypeScript
言語固有の技
Python
-
リスト内包表記
array = [1, 2, 3, 4, 5] new_array = [x for x in array if x > 2] print(new_array) # [3, 4, 5] # 辞書でも同じようなことができる dic = {'k1': 1, 'k2': 2, 'k3': 3, 'k4': 4, 'k5': 5} new_dic = {k: v for k, v in dic.items() if v > 2} print(new_dic) # {'k3': 3, 'k4': 4, 'k5': 5} # 1~100の範囲で奇数のみの配列を作る、なんてことも1行で可能 print([x for x in range(100) if x % 2]) # [1, 3, 5, 7, 9 ... , 99]
TypeScript
-
const obj = { k1: 1, k2: 2, k3: 3, k4: 4, k5: 5 } const { k1, k2, k3, k4, k5 } = obj console.log(k1) // 1 console.log(k2) // 2 console.log(k3) // 3 console.log(k4) // 4 console.log(k5) // 5
-
const obj = { k1: 1, k2: 2, k3: 3, k4: 4, k5: 5 } const { k1, k2, ...other } = obj console.log(k1) // 1 console.log(k2) // 2 console.log(other) // { "k3": 3, "k4": 4, "k5": 5 }