Typescript Typeguard 检查数组是否属于类型
Typescript Typeguard check if array is of type
我想写一个类型保护来检查数组的所有子项是否都是类型 T 从而使它成为一个数组,其中 T 是一个通用类型
// Assume arr of any type but Array
const arr: any[] = [
{
foo: "bleh1",
bar: 1
},
{
foo: "bleh2",
bar: 2
},
]
interface newType {
foo: string
bar: number
}
// Check that arr is an array of newType , ie arr: newType[]
const isArrayOf = <T,>(arr: any): arr is Array<T> => {
// TypeScript mastery needed here
return true
}
if(isArrayOf<newType>(arr)){
arr
}
你能做的最好的事情是:
const arr: NewType[] = [
{
foo: "bleh1",
bar: 1
},
{
foo: "bleh2",
bar: 2
},
]
interface NewType {
foo: string
bar: number
}
type TypeOfArrayElements<T> = T extends Array<infer U> ? U : never;
type ArrayType = TypeOfArrayElements<typeof arr>;
TypeScript 永远无法猜测类型为 any[]
的数组实际上包含 NewType
个元素。与 TypeScript 中的所有内容一样,type predicates 是静态的,不会 return 基于运行时作为参数传递的动态类型。但是,如果您将其键入为 NewType[]
,则可以从中提取 NewType
类型。
编辑 1:
这个答案有两个缺点(在评论中提到)
- 属性 不需要拥有它就可以存在于对象
x = {a: 1}; y = Object.create(x); y.b = 2
- 该功能需要您手动枚举对象的所有键。因此会引入人为错误
我认为该解决方案在特定情况下仍可用作解决方法
原文:
如果数组 a
是 newType[]
类型,那么考虑 x = a[0]
的每个元素都是 newType
类型。 x
是 newType
类型,因为 x
满足 newType
.
类型的所有属性和方法
因此如果反转,如果 x
y
z
是类型 newType
并且它们是数组 a
的唯一和所有元素,因此a
的每个元素都是 newType
类型,满足 a
是 newType[]
类型的条件
// Check if obj has all keys props[]
const hasAllProperties = <T,>(obj: any, props: (keyof T)[]): obj is T => {
return props.every((prop) => {
// console.log(prop)
return Object.prototype.hasOwnProperty.call(obj, prop)})
}
// Check that arr is an array of newType , ie arr: newType[]
const isArrayOf = <T,>(obj: any[], props: (keyof T)[]): obj is T[] => {
// Check if every elements have all keys in props
return obj.every((ele) => {
// console.log(ele)
return hasAllProperties<T>(ele,props)
}
)
}
if (isArrayOf<newType>(arr, ["foo", "bar"])) {
console.log("arr is of newType[]")
}
我想写一个类型保护来检查数组的所有子项是否都是类型 T 从而使它成为一个数组,其中 T 是一个通用类型
// Assume arr of any type but Array
const arr: any[] = [
{
foo: "bleh1",
bar: 1
},
{
foo: "bleh2",
bar: 2
},
]
interface newType {
foo: string
bar: number
}
// Check that arr is an array of newType , ie arr: newType[]
const isArrayOf = <T,>(arr: any): arr is Array<T> => {
// TypeScript mastery needed here
return true
}
if(isArrayOf<newType>(arr)){
arr
}
你能做的最好的事情是:
const arr: NewType[] = [
{
foo: "bleh1",
bar: 1
},
{
foo: "bleh2",
bar: 2
},
]
interface NewType {
foo: string
bar: number
}
type TypeOfArrayElements<T> = T extends Array<infer U> ? U : never;
type ArrayType = TypeOfArrayElements<typeof arr>;
TypeScript 永远无法猜测类型为 any[]
的数组实际上包含 NewType
个元素。与 TypeScript 中的所有内容一样,type predicates 是静态的,不会 return 基于运行时作为参数传递的动态类型。但是,如果您将其键入为 NewType[]
,则可以从中提取 NewType
类型。
编辑 1:
这个答案有两个缺点(在评论中提到)
- 属性 不需要拥有它就可以存在于对象
x = {a: 1}; y = Object.create(x); y.b = 2
- 该功能需要您手动枚举对象的所有键。因此会引入人为错误
我认为该解决方案在特定情况下仍可用作解决方法
原文:
如果数组 a
是 newType[]
类型,那么考虑 x = a[0]
的每个元素都是 newType
类型。 x
是 newType
类型,因为 x
满足 newType
.
因此如果反转,如果 x
y
z
是类型 newType
并且它们是数组 a
的唯一和所有元素,因此a
的每个元素都是 newType
类型,满足 a
是 newType[]
// Check if obj has all keys props[]
const hasAllProperties = <T,>(obj: any, props: (keyof T)[]): obj is T => {
return props.every((prop) => {
// console.log(prop)
return Object.prototype.hasOwnProperty.call(obj, prop)})
}
// Check that arr is an array of newType , ie arr: newType[]
const isArrayOf = <T,>(obj: any[], props: (keyof T)[]): obj is T[] => {
// Check if every elements have all keys in props
return obj.every((ele) => {
// console.log(ele)
return hasAllProperties<T>(ele,props)
}
)
}
if (isArrayOf<newType>(arr, ["foo", "bar"])) {
console.log("arr is of newType[]")
}