Tyl*_*ick 5 typescript typescript-generics
作为我之前问题的后续......
valueProp有没有办法在以下示例中提供默认值?
type ValueType = 'value' | 'defaultValue'
type Props<T extends ValueType> =
Record<T, string>
& { other: string }
function props<T extends ValueType>(valueProp: T): Props<T> {
return {
[valueProp]: 'value',
other: 'other',
} as Props<T>
}
let { defaultValue, other } = props('defaultValue') // ok
let { value } = props('value') // ok
Run Code Online (Sandbox Code Playgroud)
当我尝试这个时:
function props<T extends ValueType>(valueProp: T = 'value'): Props<T> {
return {
[valueProp]: 'value',
other: 'other',
} as Props<T>
}
Run Code Online (Sandbox Code Playgroud)
,我收到此错误:
Type '"value"' is not assignable to type 'T'.
'"value"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'ValueType'.
Run Code Online (Sandbox Code Playgroud)
我一般了解此错误(1 , 2 , 3 , 4),但仍然不总是知道解决此错误的最佳方法。
有没有一种简单的方法可以完成我想做的事情?
似乎应该有一种简单的方法来提供默认值,但也许默认值与泛型类型约束不能很好地混合?
我试过这个:
function props<T extends ValueType = 'value'>(valueProp: T = 'value'): Props<T> {
return {
[valueProp]: 'value',
other: 'other',
} as Props<T>
}
Run Code Online (Sandbox Code Playgroud)
但当然得到了同样的错误,因为defaultValue如果提供了特定的T 仍然可能是T:
props<'defaultValue'>()
Run Code Online (Sandbox Code Playgroud)
我想过这样做,它可以编译,但仍然不能阻止valueProp与 T 的不同意见:
function props<T extends ValueType>(valueProp: T = 'value' as T): Props<T> {
return {
[valueProp]: 'value',
other: 'other',
} as Props<T>
}
console.log(props<'defaultValue'>())
// => {value: "value", other: "other"}
Run Code Online (Sandbox Code Playgroud)
我仍然希望有一个简单的解决方案,但如果没有,也许更复杂的东西可以工作?
也许使用从类型映射到该类型的默认值的映射表?
为了获得灵感,也许是这样的:
根据 Titian Cernicova-Dragomir 的评论,我们可以使用函数重载非常简单地做到这一点:
type ValueType = 'value' | 'defaultValue'
type Props<T extends ValueType> =
Record<T, string>
& { other: string }
function props<T extends ValueType>(valueProp: T): Props<T>
function props(): Props<'value'>
function props(valueProp: ValueType | undefined = 'value') {
return {
[valueProp]: 'value',
other: 'other',
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果我们想valueProp从位置参数转移到伪命名参数(使用对象解构):
type PropsOptions<VT extends ValueType | undefined> = {
valueProp?: VT
}
function props<VT extends ValueType>({valueProp}: PropsOptions<VT>): Props<VT>
function props(): Props<'value'>
function props({ valueProp = 'value' }: PropsOptions<ValueType | undefined> = {}) {
return {
[valueProp]: 'value',
other: 'other',
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3304 次 |
| 最近记录: |