export function determineJsiiType()

in src/jsii/jsii-types.ts [14:82]


export function determineJsiiType(typeChecker: ts.TypeChecker, type: ts.Type): JsiiType {
  // this means the snippet didn't have enough info for the TypeScript compiler to figure out the type -
  // so, just render the fallback
  if ((type as any).intrinsicName === 'error') {
    return { kind: 'unknown' };
  }

  // The non-nullable version of `void` is `never`, so check first...
  if ((type.flags & (ts.TypeFlags.Void | ts.TypeFlags.VoidLike)) !== 0) {
    return { kind: 'builtIn', builtIn: 'void' };
  }
  // The non-nullable version of `unknown` is some ObjectType, so check first...
  if ((type.flags & (ts.TypeFlags.Unknown | ts.TypeFlags.Any)) !== 0) {
    return { kind: 'builtIn', builtIn: 'any' };
  }

  type = type.getNonNullableType();

  const mapValuesType = mapElementType(type, typeChecker);
  if (mapValuesType.result === 'map') {
    return {
      kind: 'map',
      elementType: mapValuesType.elementType
        ? determineJsiiType(typeChecker, mapValuesType.elementType)
        : { kind: 'builtIn', builtIn: 'any' },
      elementTypeSymbol: mapValuesType.elementType?.symbol,
    };
  }

  if (type.symbol?.name === 'Array') {
    const typeRef = type as ts.TypeReference;

    if (typeRef.typeArguments?.length === 1) {
      return {
        kind: 'list',
        elementType: determineJsiiType(typeChecker, typeRef.typeArguments[0]),
        elementTypeSymbol: typeRef.typeArguments[0].symbol,
      };
    }

    return {
      kind: 'list',
      elementType: { kind: 'builtIn', builtIn: 'any' },
      elementTypeSymbol: undefined,
    };
  }

  // User-defined or aliased type
  if (type.aliasSymbol) {
    return { kind: 'namedType', name: type.aliasSymbol.name };
  }
  if (type.symbol) {
    return { kind: 'namedType', name: type.symbol.name };
  }

  const typeScriptBuiltInType = builtInTypeName(type);
  if (typeScriptBuiltInType) {
    return { kind: 'builtIn', builtIn: typeScriptBuiltInType };
  }

  if (type.isUnion() || type.isIntersection()) {
    return {
      kind: 'error',
      message: `Type unions or intersections are not supported in examples, got: ${typeChecker.typeToString(type)}`,
    };
  }

  return { kind: 'unknown' };
}