Add intersection types in react-native-codegen for TypeScript (#35247)
Summary: Refer to "Support intersection of object types, `{...a, ...b, ...}` in Flow is equivalent to `a & b & {...}` in TypeScript, the order and the form is not important." in https://github.com/facebook/react-native/issues/34872 In this change I also extract the common part from `getTypeAnnotation` and `getTypeAnnotationForArray` into `getCommonTypeAnnotation`. Most of the differences are about `default` in the schema. After a schema is generated from `getCommonTypeAnnotation` successfully, `getTypeAnnotation` will fill `default` if necessary, while `getTypeAnnotationForArray` does nothing. ## Changelog [General] [Changed] - Add intersection types in react-native-codegen for TypeScript Pull Request resolved: https://github.com/facebook/react-native/pull/35247 Test Plan: `yarn jest react-native-codegen` passed Reviewed By: cipolleschi Differential Revision: D41105744 Pulled By: lunaleaps fbshipit-source-id: cd250a9594a54596a20ae26e57a1c801e2047703
This commit is contained in:
Родитель
63a4539e4d
Коммит
813fd04118
|
@ -21,7 +21,7 @@ const tsExtraCases = [
|
||||||
'ARRAY2_PROP_TYPES_NO_EVENTS',
|
'ARRAY2_PROP_TYPES_NO_EVENTS',
|
||||||
'PROPS_AND_EVENTS_WITH_INTERFACES',
|
'PROPS_AND_EVENTS_WITH_INTERFACES',
|
||||||
];
|
];
|
||||||
const ignoredCases = ['ARRAY_PROP_TYPES_NO_EVENTS'];
|
const ignoredCases = [];
|
||||||
|
|
||||||
compareSnaps(
|
compareSnaps(
|
||||||
flowFixtures,
|
flowFixtures,
|
||||||
|
|
|
@ -452,6 +452,13 @@ export interface ModuleProps extends ViewProps {
|
||||||
array_of_array_of_object_required_in_file: ReadonlyArray<
|
array_of_array_of_object_required_in_file: ReadonlyArray<
|
||||||
ReadonlyArray<ObjectType>
|
ReadonlyArray<ObjectType>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
// Nested array of array of object types (with spread)
|
||||||
|
array_of_array_of_object_required_with_spread: ReadonlyArray<
|
||||||
|
ReadonlyArray<
|
||||||
|
Readonly<ObjectType & {}>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default codegenNativeComponent<ModuleProps>(
|
export default codegenNativeComponent<ModuleProps>(
|
||||||
|
@ -584,6 +591,9 @@ export interface ModuleProps extends ViewProps {
|
||||||
|
|
||||||
// Nested array of array of object types (in file)
|
// Nested array of array of object types (in file)
|
||||||
array_of_array_of_object_required_in_file: readonly ObjectType[][];
|
array_of_array_of_object_required_in_file: readonly ObjectType[][];
|
||||||
|
|
||||||
|
// Nested array of array of object types (with spread)
|
||||||
|
array_of_array_of_object_required_with_spread: readonly Readonly<ObjectType & {}>[][];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default codegenNativeComponent<ModuleProps>(
|
export default codegenNativeComponent<ModuleProps>(
|
||||||
|
|
|
@ -1221,6 +1221,29 @@ exports[`RN Codegen TypeScript Parser can generate fixture ARRAY_PROP_TYPES_NO_E
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'array_of_array_of_object_required_with_spread',
|
||||||
|
'optional': false,
|
||||||
|
'typeAnnotation': {
|
||||||
|
'type': 'ArrayTypeAnnotation',
|
||||||
|
'elementType': {
|
||||||
|
'type': 'ArrayTypeAnnotation',
|
||||||
|
'elementType': {
|
||||||
|
'type': 'ObjectTypeAnnotation',
|
||||||
|
'properties': [
|
||||||
|
{
|
||||||
|
'name': 'prop',
|
||||||
|
'optional': false,
|
||||||
|
'typeAnnotation': {
|
||||||
|
'type': 'StringTypeAnnotation',
|
||||||
|
'default': null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'commands': []
|
'commands': []
|
||||||
|
@ -1905,6 +1928,29 @@ exports[`RN Codegen TypeScript Parser can generate fixture ARRAY2_PROP_TYPES_NO_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'array_of_array_of_object_required_with_spread',
|
||||||
|
'optional': false,
|
||||||
|
'typeAnnotation': {
|
||||||
|
'type': 'ArrayTypeAnnotation',
|
||||||
|
'elementType': {
|
||||||
|
'type': 'ArrayTypeAnnotation',
|
||||||
|
'elementType': {
|
||||||
|
'type': 'ObjectTypeAnnotation',
|
||||||
|
'properties': [
|
||||||
|
{
|
||||||
|
'name': 'prop',
|
||||||
|
'optional': false,
|
||||||
|
'typeAnnotation': {
|
||||||
|
'type': 'StringTypeAnnotation',
|
||||||
|
'default': null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'commands': []
|
'commands': []
|
||||||
|
|
|
@ -11,7 +11,10 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
import type {ASTNode} from '../utils';
|
import type {ASTNode} from '../utils';
|
||||||
import type {NamedShape} from '../../../CodegenSchema.js';
|
import type {NamedShape} from '../../../CodegenSchema.js';
|
||||||
const {parseTopLevelType} = require('../parseTopLevelType');
|
const {
|
||||||
|
parseTopLevelType,
|
||||||
|
flattenIntersectionType,
|
||||||
|
} = require('../parseTopLevelType');
|
||||||
import type {TypeDeclarationMap} from '../../utils';
|
import type {TypeDeclarationMap} from '../../utils';
|
||||||
|
|
||||||
function getProperties(
|
function getProperties(
|
||||||
|
@ -163,6 +166,102 @@ function detectArrayType<T>(
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildObjectType<T>(
|
||||||
|
rawProperties: Array<$FlowFixMe>,
|
||||||
|
types: TypeDeclarationMap,
|
||||||
|
buildSchema: (property: PropAST, types: TypeDeclarationMap) => ?NamedShape<T>,
|
||||||
|
): $FlowFixMe {
|
||||||
|
const flattenedProperties = flattenProperties(rawProperties, types);
|
||||||
|
const properties = flattenedProperties
|
||||||
|
.map(prop => buildSchema(prop, types))
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'ObjectTypeAnnotation',
|
||||||
|
properties,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCommonTypeAnnotation<T>(
|
||||||
|
name: string,
|
||||||
|
forArray: boolean,
|
||||||
|
type: string,
|
||||||
|
typeAnnotation: $FlowFixMe,
|
||||||
|
defaultValue: $FlowFixMe | void,
|
||||||
|
types: TypeDeclarationMap,
|
||||||
|
buildSchema: (property: PropAST, types: TypeDeclarationMap) => ?NamedShape<T>,
|
||||||
|
): $FlowFixMe {
|
||||||
|
switch (type) {
|
||||||
|
case 'TSTypeLiteral':
|
||||||
|
return buildObjectType(typeAnnotation.members, types, buildSchema);
|
||||||
|
case 'TSInterfaceDeclaration':
|
||||||
|
return buildObjectType([typeAnnotation], types, buildSchema);
|
||||||
|
case 'TSIntersectionType':
|
||||||
|
return buildObjectType(
|
||||||
|
flattenIntersectionType(typeAnnotation, types),
|
||||||
|
types,
|
||||||
|
buildSchema,
|
||||||
|
);
|
||||||
|
case 'ImageSource':
|
||||||
|
return {
|
||||||
|
type: 'ReservedPropTypeAnnotation',
|
||||||
|
name: 'ImageSourcePrimitive',
|
||||||
|
};
|
||||||
|
case 'ImageRequest':
|
||||||
|
return {
|
||||||
|
type: 'ReservedPropTypeAnnotation',
|
||||||
|
name: 'ImageRequestPrimitive',
|
||||||
|
};
|
||||||
|
case 'ColorValue':
|
||||||
|
case 'ProcessedColorValue':
|
||||||
|
return {
|
||||||
|
type: 'ReservedPropTypeAnnotation',
|
||||||
|
name: 'ColorPrimitive',
|
||||||
|
};
|
||||||
|
case 'PointValue':
|
||||||
|
return {
|
||||||
|
type: 'ReservedPropTypeAnnotation',
|
||||||
|
name: 'PointPrimitive',
|
||||||
|
};
|
||||||
|
case 'EdgeInsetsValue':
|
||||||
|
return {
|
||||||
|
type: 'ReservedPropTypeAnnotation',
|
||||||
|
name: 'EdgeInsetsPrimitive',
|
||||||
|
};
|
||||||
|
case 'TSUnionType':
|
||||||
|
return getUnionOfLiterals(
|
||||||
|
name,
|
||||||
|
forArray,
|
||||||
|
typeAnnotation.types,
|
||||||
|
defaultValue,
|
||||||
|
types,
|
||||||
|
);
|
||||||
|
case 'Int32':
|
||||||
|
return {
|
||||||
|
type: 'Int32TypeAnnotation',
|
||||||
|
};
|
||||||
|
case 'Double':
|
||||||
|
return {
|
||||||
|
type: 'DoubleTypeAnnotation',
|
||||||
|
};
|
||||||
|
case 'Float':
|
||||||
|
return {
|
||||||
|
type: 'FloatTypeAnnotation',
|
||||||
|
};
|
||||||
|
case 'TSBooleanKeyword':
|
||||||
|
return {
|
||||||
|
type: 'BooleanTypeAnnotation',
|
||||||
|
};
|
||||||
|
case 'Stringish':
|
||||||
|
case 'TSStringKeyword':
|
||||||
|
return {
|
||||||
|
type: 'StringTypeAnnotation',
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getTypeAnnotationForArray<T>(
|
function getTypeAnnotationForArray<T>(
|
||||||
name: string,
|
name: string,
|
||||||
typeAnnotation: $FlowFixMe,
|
typeAnnotation: $FlowFixMe,
|
||||||
|
@ -207,91 +306,57 @@ function getTypeAnnotationForArray<T>(
|
||||||
extractedTypeAnnotation.typeName?.name ||
|
extractedTypeAnnotation.typeName?.name ||
|
||||||
extractedTypeAnnotation.type;
|
extractedTypeAnnotation.type;
|
||||||
|
|
||||||
|
const common = getCommonTypeAnnotation(
|
||||||
|
name,
|
||||||
|
true,
|
||||||
|
type,
|
||||||
|
extractedTypeAnnotation,
|
||||||
|
defaultValue,
|
||||||
|
types,
|
||||||
|
buildSchema,
|
||||||
|
);
|
||||||
|
if (common) {
|
||||||
|
return common;
|
||||||
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'TSTypeLiteral':
|
|
||||||
case 'TSInterfaceDeclaration': {
|
|
||||||
const rawProperties =
|
|
||||||
type === 'TSInterfaceDeclaration'
|
|
||||||
? [extractedTypeAnnotation]
|
|
||||||
: extractedTypeAnnotation.members;
|
|
||||||
if (rawProperties === undefined) {
|
|
||||||
throw new Error(type);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
type: 'ObjectTypeAnnotation',
|
|
||||||
properties: flattenProperties(rawProperties, types)
|
|
||||||
.map(prop => buildSchema(prop, types))
|
|
||||||
.filter(Boolean),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case 'TSNumberKeyword':
|
case 'TSNumberKeyword':
|
||||||
return {
|
return {
|
||||||
type: 'FloatTypeAnnotation',
|
type: 'FloatTypeAnnotation',
|
||||||
};
|
};
|
||||||
case 'ImageSource':
|
|
||||||
return {
|
|
||||||
type: 'ReservedPropTypeAnnotation',
|
|
||||||
name: 'ImageSourcePrimitive',
|
|
||||||
};
|
|
||||||
case 'ImageRequest':
|
|
||||||
return {
|
|
||||||
type: 'ReservedPropTypeAnnotation',
|
|
||||||
name: 'ImageRequestPrimitive',
|
|
||||||
};
|
|
||||||
case 'ColorValue':
|
|
||||||
case 'ProcessedColorValue':
|
|
||||||
return {
|
|
||||||
type: 'ReservedPropTypeAnnotation',
|
|
||||||
name: 'ColorPrimitive',
|
|
||||||
};
|
|
||||||
case 'PointValue':
|
|
||||||
return {
|
|
||||||
type: 'ReservedPropTypeAnnotation',
|
|
||||||
name: 'PointPrimitive',
|
|
||||||
};
|
|
||||||
case 'EdgeInsetsValue':
|
|
||||||
return {
|
|
||||||
type: 'ReservedPropTypeAnnotation',
|
|
||||||
name: 'EdgeInsetsPrimitive',
|
|
||||||
};
|
|
||||||
case 'Stringish':
|
|
||||||
return {
|
|
||||||
type: 'StringTypeAnnotation',
|
|
||||||
};
|
|
||||||
case 'Int32':
|
|
||||||
return {
|
|
||||||
type: 'Int32TypeAnnotation',
|
|
||||||
};
|
|
||||||
case 'Double':
|
|
||||||
return {
|
|
||||||
type: 'DoubleTypeAnnotation',
|
|
||||||
};
|
|
||||||
case 'Float':
|
|
||||||
return {
|
|
||||||
type: 'FloatTypeAnnotation',
|
|
||||||
};
|
|
||||||
case 'TSBooleanKeyword':
|
|
||||||
return {
|
|
||||||
type: 'BooleanTypeAnnotation',
|
|
||||||
};
|
|
||||||
case 'TSStringKeyword':
|
|
||||||
return {
|
|
||||||
type: 'StringTypeAnnotation',
|
|
||||||
};
|
|
||||||
case 'TSUnionType':
|
|
||||||
return getUnionOfLiterals(
|
|
||||||
name,
|
|
||||||
true,
|
|
||||||
extractedTypeAnnotation.types,
|
|
||||||
defaultValue,
|
|
||||||
types,
|
|
||||||
);
|
|
||||||
default:
|
default:
|
||||||
(type: empty);
|
(type: empty);
|
||||||
throw new Error(`Unknown prop type for "${name}": ${type}`);
|
throw new Error(`Unknown prop type for "${name}": ${type}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setDefaultValue(
|
||||||
|
common: $FlowFixMe,
|
||||||
|
defaultValue: $FlowFixMe | void,
|
||||||
|
): void {
|
||||||
|
switch (common.type) {
|
||||||
|
case 'Int32TypeAnnotation':
|
||||||
|
case 'DoubleTypeAnnotation':
|
||||||
|
common.default = ((defaultValue ? defaultValue : 0): number);
|
||||||
|
break;
|
||||||
|
case 'FloatTypeAnnotation':
|
||||||
|
common.default = ((defaultValue === null
|
||||||
|
? null
|
||||||
|
: defaultValue
|
||||||
|
? defaultValue
|
||||||
|
: 0): number | null);
|
||||||
|
break;
|
||||||
|
case 'BooleanTypeAnnotation':
|
||||||
|
common.default = defaultValue === null ? null : !!defaultValue;
|
||||||
|
break;
|
||||||
|
case 'StringTypeAnnotation':
|
||||||
|
common.default = ((defaultValue === undefined ? null : defaultValue):
|
||||||
|
| string
|
||||||
|
| null);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getTypeAnnotation<T>(
|
function getTypeAnnotation<T>(
|
||||||
name: string,
|
name: string,
|
||||||
annotation: $FlowFixMe | ASTNode,
|
annotation: $FlowFixMe | ASTNode,
|
||||||
|
@ -319,39 +384,21 @@ function getTypeAnnotation<T>(
|
||||||
? typeAnnotation.typeName.name
|
? typeAnnotation.typeName.name
|
||||||
: typeAnnotation.type;
|
: typeAnnotation.type;
|
||||||
|
|
||||||
switch (type) {
|
const common = getCommonTypeAnnotation(
|
||||||
case 'TSTypeLiteral':
|
name,
|
||||||
case 'TSInterfaceDeclaration': {
|
false,
|
||||||
const rawProperties =
|
type,
|
||||||
type === 'TSInterfaceDeclaration'
|
typeAnnotation,
|
||||||
? [typeAnnotation]
|
defaultValue,
|
||||||
: typeAnnotation.members;
|
types,
|
||||||
const flattenedProperties = flattenProperties(rawProperties, types);
|
buildSchema,
|
||||||
const properties = flattenedProperties
|
);
|
||||||
.map(prop => buildSchema(prop, types))
|
if (common) {
|
||||||
.filter(Boolean);
|
setDefaultValue(common, defaultValue);
|
||||||
|
return common;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
switch (type) {
|
||||||
type: 'ObjectTypeAnnotation',
|
|
||||||
properties,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case 'ImageSource':
|
|
||||||
return {
|
|
||||||
type: 'ReservedPropTypeAnnotation',
|
|
||||||
name: 'ImageSourcePrimitive',
|
|
||||||
};
|
|
||||||
case 'ImageRequest':
|
|
||||||
return {
|
|
||||||
type: 'ReservedPropTypeAnnotation',
|
|
||||||
name: 'ImageRequestPrimitive',
|
|
||||||
};
|
|
||||||
case 'ColorValue':
|
|
||||||
case 'ProcessedColorValue':
|
|
||||||
return {
|
|
||||||
type: 'ReservedPropTypeAnnotation',
|
|
||||||
name: 'ColorPrimitive',
|
|
||||||
};
|
|
||||||
case 'ColorArrayValue':
|
case 'ColorArrayValue':
|
||||||
return {
|
return {
|
||||||
type: 'ArrayTypeAnnotation',
|
type: 'ArrayTypeAnnotation',
|
||||||
|
@ -360,66 +407,10 @@ function getTypeAnnotation<T>(
|
||||||
name: 'ColorPrimitive',
|
name: 'ColorPrimitive',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
case 'PointValue':
|
|
||||||
return {
|
|
||||||
type: 'ReservedPropTypeAnnotation',
|
|
||||||
name: 'PointPrimitive',
|
|
||||||
};
|
|
||||||
case 'EdgeInsetsValue':
|
|
||||||
return {
|
|
||||||
type: 'ReservedPropTypeAnnotation',
|
|
||||||
name: 'EdgeInsetsPrimitive',
|
|
||||||
};
|
|
||||||
case 'Int32':
|
|
||||||
return {
|
|
||||||
type: 'Int32TypeAnnotation',
|
|
||||||
default: ((defaultValue ? defaultValue : 0): number),
|
|
||||||
};
|
|
||||||
case 'Double':
|
|
||||||
return {
|
|
||||||
type: 'DoubleTypeAnnotation',
|
|
||||||
default: ((defaultValue ? defaultValue : 0): number),
|
|
||||||
};
|
|
||||||
case 'Float':
|
|
||||||
return {
|
|
||||||
type: 'FloatTypeAnnotation',
|
|
||||||
default: ((defaultValue === null
|
|
||||||
? null
|
|
||||||
: defaultValue
|
|
||||||
? defaultValue
|
|
||||||
: 0): number | null),
|
|
||||||
};
|
|
||||||
case 'TSBooleanKeyword':
|
|
||||||
return {
|
|
||||||
type: 'BooleanTypeAnnotation',
|
|
||||||
default: defaultValue === null ? null : !!defaultValue,
|
|
||||||
};
|
|
||||||
case 'TSStringKeyword':
|
|
||||||
return {
|
|
||||||
type: 'StringTypeAnnotation',
|
|
||||||
default: ((defaultValue === undefined ? null : defaultValue):
|
|
||||||
| string
|
|
||||||
| null),
|
|
||||||
};
|
|
||||||
case 'Stringish':
|
|
||||||
return {
|
|
||||||
type: 'StringTypeAnnotation',
|
|
||||||
default: ((defaultValue === undefined ? null : defaultValue):
|
|
||||||
| string
|
|
||||||
| null),
|
|
||||||
};
|
|
||||||
case 'TSNumberKeyword':
|
case 'TSNumberKeyword':
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Cannot use "${type}" type annotation for "${name}": must use a specific numeric type like Int32, Double, or Float`,
|
`Cannot use "${type}" type annotation for "${name}": must use a specific numeric type like Int32, Double, or Float`,
|
||||||
);
|
);
|
||||||
case 'TSUnionType':
|
|
||||||
return getUnionOfLiterals(
|
|
||||||
name,
|
|
||||||
false,
|
|
||||||
typeAnnotation.types,
|
|
||||||
defaultValue,
|
|
||||||
types,
|
|
||||||
);
|
|
||||||
default:
|
default:
|
||||||
(type: empty);
|
(type: empty);
|
||||||
throw new Error(`Unknown prop type for "${name}": "${type}"`);
|
throw new Error(`Unknown prop type for "${name}": "${type}"`);
|
||||||
|
@ -498,6 +489,8 @@ function flattenProperties(
|
||||||
return flattenProperties(property.members, types);
|
return flattenProperties(property.members, types);
|
||||||
} else if (property.type === 'TSInterfaceDeclaration') {
|
} else if (property.type === 'TSInterfaceDeclaration') {
|
||||||
return flattenProperties(getProperties(property.id.name, types), types);
|
return flattenProperties(getProperties(property.id.name, types), types);
|
||||||
|
} else if (property.type === 'TSIntersectionType') {
|
||||||
|
return flattenProperties(property.types, types);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`${property.type} is not a supported object literal type.`,
|
`${property.type} is not a supported object literal type.`,
|
||||||
|
|
|
@ -184,6 +184,60 @@ function parseTopLevelType(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleIntersectionAndParen(
|
||||||
|
type: $FlowFixMe,
|
||||||
|
result: Array<$FlowFixMe>,
|
||||||
|
knownTypes?: TypeDeclarationMap,
|
||||||
|
): void {
|
||||||
|
switch (type.type) {
|
||||||
|
case 'TSParenthesizedType': {
|
||||||
|
handleIntersectionAndParen(type.typeAnnotation, result, knownTypes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'TSIntersectionType': {
|
||||||
|
for (const t of type.types) {
|
||||||
|
handleIntersectionAndParen(t, result, knownTypes);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'TSTypeReference':
|
||||||
|
if (type.typeName.name === 'Readonly') {
|
||||||
|
handleIntersectionAndParen(
|
||||||
|
type.typeParameters.params[0],
|
||||||
|
result,
|
||||||
|
knownTypes,
|
||||||
|
);
|
||||||
|
} else if (type.typeName.name === 'WithDefault') {
|
||||||
|
throw new Error('WithDefault<> is now allowed in intersection types.');
|
||||||
|
} else if (!knownTypes) {
|
||||||
|
result.push(type);
|
||||||
|
} else {
|
||||||
|
const resolvedType = getValueFromTypes(type, knownTypes);
|
||||||
|
if (
|
||||||
|
resolvedType.type === 'TSTypeReference' &&
|
||||||
|
resolvedType.typeName.name === type.typeName.name
|
||||||
|
) {
|
||||||
|
result.push(type);
|
||||||
|
} else {
|
||||||
|
handleIntersectionAndParen(resolvedType, result, knownTypes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result.push(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function flattenIntersectionType(
|
||||||
|
type: $FlowFixMe,
|
||||||
|
knownTypes?: TypeDeclarationMap,
|
||||||
|
): Array<$FlowFixMe> {
|
||||||
|
const result: Array<$FlowFixMe> = [];
|
||||||
|
handleIntersectionAndParen(type, result, knownTypes);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
parseTopLevelType,
|
parseTopLevelType,
|
||||||
|
flattenIntersectionType,
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче