{ [K in keyof Pick<O, DefaultKeys<O>>]: InferPropType<O[K]> }
: {}
-type NormalizedProp =
- | null
- | (PropOptions & {
- [BooleanFlags.shouldCast]?: boolean
- [BooleanFlags.shouldCastTrue]?: boolean
- })
+type NormalizedProp = PropOptions & {
+ [BooleanFlags.shouldCast]?: boolean
+ [BooleanFlags.shouldCastTrue]?: boolean
+}
// normalized value is a tuple of the actual normalized options
// and an array of prop keys that need value casting (booleans and defaults)
const opt = raw[key]
const prop: NormalizedProp = (normalized[normalizedKey] =
isArray(opt) || isFunction(opt) ? { type: opt } : extend({}, opt))
- if (prop) {
- const booleanIndex = getTypeIndex(Boolean, prop.type)
- const stringIndex = getTypeIndex(String, prop.type)
- prop[BooleanFlags.shouldCast] = booleanIndex > -1
- prop[BooleanFlags.shouldCastTrue] =
- stringIndex < 0 || booleanIndex < stringIndex
- // if the prop needs boolean casting or default value
- if (booleanIndex > -1 || hasOwn(prop, 'default')) {
- needCastKeys.push(normalizedKey)
+ const propType = prop.type
+ let shouldCast = false
+ let shouldCastTrue = true
+
+ if (isArray(propType)) {
+ for (let index = 0; index < propType.length; ++index) {
+ const type = propType[index]
+ const typeName = isFunction(type) && type.name
+
+ if (typeName === 'Boolean') {
+ shouldCast = true
+ break
+ } else if (typeName === 'String') {
+ // If we find `String` before `Boolean`, e.g. `[String, Boolean]`,
+ // we need to handle the casting slightly differently. Props
+ // passed as `<Comp checked="">` or `<Comp checked="checked">`
+ // will either be treated as strings or converted to a boolean
+ // `true`, depending on the order of the types.
+ shouldCastTrue = false
+ }
}
+ } else {
+ shouldCast = isFunction(propType) && propType.name === 'Boolean'
+ }
+
+ prop[BooleanFlags.shouldCast] = shouldCast
+ prop[BooleanFlags.shouldCastTrue] = shouldCastTrue
+ // if the prop needs boolean casting or default value
+ if (shouldCast || hasOwn(prop, 'default')) {
+ needCastKeys.push(normalizedKey)
}
}
}
return false
}
+// dev only
// use function string name to check type constructors
// so that it works across vms / iframes.
function getType(ctor: Prop<any>): string {
return ''
}
-function isSameType(a: Prop<any>, b: Prop<any>): boolean {
- return getType(a) === getType(b)
-}
-
-function getTypeIndex(
- type: Prop<any>,
- expectedTypes: PropType<any> | void | null | true,
-): number {
- if (isArray(expectedTypes)) {
- return expectedTypes.findIndex(t => isSameType(t, type))
- } else if (isFunction(expectedTypes)) {
- return isSameType(expectedTypes, type) ? 0 : -1
- }
- return -1
-}
-
/**
* dev only
*/