例えば下記のようなエラーが出た時の対応。
型を確定させないと出るエラー。
error: Type 'T' is not assignable to type 'string'.
error: Type 'object | null' is not assignable to type 'object'.
Type 'null' is not assignable to type 'object'.
error: Type 'string | null' is not assignable to type 'string'.
Type 'null' is not assignable to type 'string'.
error: Element implicitly has an 'any' type because index expression is not of type 'number'.
error: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof Fruit'.
No index signature with a parameter of type 'string' was found on type 'typeof Fruit'.
error: Property 'append' does not exist on type 'U'.
error: Argument of type 'unknown' is not assignable to parameter of type 'string'.
環境
- TypeScript v5
型ガードする
その1: null チェック
// error: Type 'string | null' is not assignable to type 'string'.
// Type 'null' is not assignable to type 'string'.
function sample(args: string | null): string {
return args
}
↓
function sample(args: string | null): string {
if (args == null) return ""
return args
}
その2: typeof
// error: Type 'T' is not assignable to type 'string'.
function sample<T>(args: T): string {
return args
}
↓
function sample<T>(args: T): string {
return (typeof args == "string") ? args : ""
}
その3: instanceof
// error: Property 'append' does not exist on type 'U'.
function sample<T, U>(params: T, webApi: U): U {
const query: object = params && typeof params == "object" ? params : {}
for (const [key, value] of Object.entries(query)) {
if (Array.isArray(value)) {
for (const [_, v] of value.entries()) {
webApi.append(key, v)
}
continue
}
webApi.append(key, value)
}
return webApi
}
sample<object, URLSearchParams>({ test: "aaaa"}, new URLSearchParams()).toString()
↓
function sample<T, U>(params: T, webApi: U): U {
const query: object = params && typeof params == "object" ? params : {}
for (const [key, value] of Object.entries(query)) {
if (Array.isArray(value)) {
for (const [_, v] of value.entries()) {
if (webApi instanceof URLSearchParams || webApi instanceof FormData) {
webApi.append(key, v)
}
}
continue
}
if (webApi instanceof URLSearchParams || webApi instanceof FormData) {
webApi.append(key, value)
}
}
return webApi
}
sample<object, URLSearchParams>({ test: "aaaa"}, new URLSearchParams()).toString()
その4: as keyof typeof
例えばこんな enum
enum Sample1 {
Apple,
Lemon,
Orange,
}
enum Sample2 {
Apple = "apple",
Lemon = "lemon",
Orange = "orange",
}
// error: Element implicitly has an 'any' type because index expression is not of type 'number'.
function sample1(): number {
let res = 0
for (const key of Object.keys(Sample1).values()) {
res = Sample1[key]
}
return res
}
// error: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof Sample2'.
// No index signature with a parameter of type 'string' was found on type 'typeof Sample2'.
function sample2(): string {
let res = ""
for (const key of Object.keys(Sample2).values()) {
res = Sample2[key]
}
return res
}
↓
function sample1(): number {
let res = 0
for (const key of Object.keys(Sample1).values()) {
res = Sample1[key as keyof typeof Sample1]
}
return res
}
function sample2(): string {
let res = ""
for (const key of Object.keys(Sample2).values()) {
res = Sample2[key as keyof typeof Sample2]
}
return res
}
その5: Array.isArray() など
// error: Argument of type 'unknown' is not assignable to parameter of type 'string'.
function sample<T, U>(params: T, webApi: U): U {
const query: object = params && typeof params == "object" ? params : {}
for (const [key, value] of Object.entries(query)) {
let foundArray = false
for (const [_, v] of Object.entries(value)) {
if (webApi instanceof URLSearchParams || webApi instanceof FormData) {
webApi.append(key, v)
foundArray = true
}
}
if (foundArray) {
continue
}
if (webApi instanceof URLSearchParams || webApi instanceof FormData) {
webApi.append(key, value)
}
}
return webApi
}
↓
function sample<T, U>(params: T, webApi: U): U {
const query: object = params && typeof params == "object" ? params : {}
for (const [key, value] of Object.entries(query)) {
if (Array.isArray(value)) {
for (const [_, v] of value.entries()) {
if (webApi instanceof URLSearchParams || webApi instanceof FormData) {
webApi.append(key, v)
}
}
continue
}
if (webApi instanceof URLSearchParams || webApi instanceof FormData) {
webApi.append(key, value)
}
}
return webApi
}