我有一个类,当我初始化它时,我传入一个值,或者一个关于该值的对象
例如
new Field<string>('test')
new Field<string>({value: 'test', inactive: 'preview'})
但是 state.value
是错误的。 (“FieldState”类型上不存在属性“value”。
类型“T”上不存在属性“值”。ts(2339))
interface BoxedValue<T> {
value: T
inactive: 'disabled'| 'preview'| 'hidden'
}
type FieldState<T> = BoxedValue<T> | T
class Field<T> {
value: T
_pendingValue: T
constructor(state: FieldState<T>) {
if(typeof state === 'object') {
this.value = this._pendingValue = state.value
} else {
this.value = this._pendingValue = state
}
}
}
谢谢你的解决方案,我修改了代码,但我现在有一个新问题。
class Field<T> {
value: T
_pendingValue: T
constructor(state: FieldState<T>) {
if(this._isBoxedValue(state)) {
this.value = this._pendingValue = state.value // Property 'value' does not exist on type 'FieldState<T>'.Property 'value' does not exist on type 'T'.
} else {
this.value = this._pendingValue = state
// Type 'FieldState<T>' is not assignable to type 'T'.
// T' could be instantiated with an arbitrary type which could be unrelated to 'FieldState<T>'.
// Type 'BoxedValue<T>' is not assignable to type 'T'.
// 'T' could be instantiated with an arbitrary type which could be unrelated to 'BoxedValue<T>'
}
}
_isBoxedValue(state: FieldState<T>): boolean{
return typeof state === 'object' && state !== null &&
Object.keys(state).length === 2 && 'value' in state && 'inactive' in state;
}
}
为什么我把判断条件放在isboxedvalue函数里的时候会出错,而在构造函数里却没有?
答案 0 :(得分:0)
嗨,这个问题不是每个人都会遇到的。您的 typeof state === "object"
是对 BoxedValue 的测试,但有一个小错误:T 也可以是一个对象。
interface BoxedValue<T> {
value: T;
inactive: 'disabled' | 'preview' | 'hidden';
}
type FieldState<T> = BoxedValue<T> | T;
class Field<T> {
value: T;
_pendingValue: T;
constructor(state: FieldState<T>) {
if (typeof state === 'object' && "value" in state) {
this.value = this._pendingValue = state.value;
} else {
this.value = this._pendingValue = state;
}
}
}
interface BoxedValue<T> {
value: T;
inactive: 'disabled' | 'preview' | 'hidden';
}
type FieldState<T> = BoxedValue<T> | T;
class Field<T extends (string | number /* or your type */)> {
value: T;
_pendingValue: T;
constructor(state: FieldState<T>) {
if (typeof state === 'object') {
this.value = this._pendingValue = state.value;
} else {
this.value = this._pendingValue = state;
}
}
}
答案 1 :(得分:0)
您应该使用 in 运算符。使用typeof state ==='object'
只能保证state
是object
类型(如果state
的值为null
,它也是object
类型),但不能保证它具有 value
属性。
in 运算符还充当类型的缩小表达式。
interface BoxedValue<T> {
value: T
inactive: 'disabled'| 'preview'| 'hidden'
}
type FieldState<T> = BoxedValue<T> | T
class Field<T> {
value: T
_pendingValue: T
constructor(state: FieldState<T>) {
if('value' in state) {
this.value = this._pendingValue = state.value
} else {
this.value = this._pendingValue = state
}
}
}
更新:
您应该将 User-Defined Type Guards 用于 _isBoxedValue
方法。返回类型 state is BoxedValue<T>
是一个类型谓词,而不是 boolean
。
例如
interface BoxedValue<T> {
value: T
inactive: 'disabled'| 'preview'| 'hidden'
}
type FieldState<T> = BoxedValue<T> | T
class Field<T> {
value: T
_pendingValue: T
constructor(state: FieldState<T>) {
if(this._isBoxedValue(state)) {
this.value = this._pendingValue = state.value;
} else {
this.value = this._pendingValue = state;
}
}
_isBoxedValue(state: FieldState<T>): state is BoxedValue<T>{
return typeof state === 'object' && state !== null &&
Object.keys(state).length === 2 && 'value' in state && 'inactive' in state;
}
}