类型生成工具未正确处理TypeScript中的可空字段

ndh0cuux  于 2023-04-22  发布在  TypeScript
关注(0)|答案(1)|浏览(94)

我正在构建一个代码生成工具,它接受我的数据库模式的输入文件作为接口,并从中生成更小的类型。

输入

export interface Database {
  public: {
    Tables: {
      profiles: {
        Row: {
          first_name: string | null;
          id: string;
          last_name: string | null;
        };
      };
    };
  };
}

预期产出

export type Profile = {
  first_name: string | null;
  id: string;
  last_name: string | null;
};

实际产量

export type Profile = {
  first_name: string;
  id: string;
  last_name: string;
};

在生成类型时,我在捕获输出的null部分时遇到了问题。

我现在拥有的

const project = new Project({
  compilerOptions: {
    allowSyntheticDefaultImports: true,
    esModuleInterop: true,
    module: ModuleKind.ESNext,
    target: ScriptTarget.ESNext,
  },
});

const sourceFile = project.addSourceFileAtPath(typesPath);

// Find the 'Tables' type alias
const databaseInterface = sourceFile.getInterfaceOrThrow('Database');
const publicProperty = databaseInterface.getPropertyOrThrow('public');
const publicType = publicProperty.getType();

const tablesProperty = publicType
  .getApparentProperties()
  .find((property) => property.getName() === 'Tables');

const tablesType = project
  .getProgram()
  .getTypeChecker()
  .getTypeAtLocation(tablesProperty.getValueDeclarationOrThrow());
const tablesProperties = tablesType.getProperties();

const types: string[] = [];

for (const table of tablesProperties) {
  const tableName = table.getName();
  types.push(...generateTypes(table, tableName));
}

...

export function generateTypes(table: Symbol, tableName: string): string[] {
  // Get the table type
  const tableType = table.getTypeAtLocation(table.getValueDeclarationOrThrow());

  // Find the 'Row' property within the table type
  const rowProperty = tableType.getProperty('Row');

  // Get the type of the 'Row' property
  const rowType = rowProperty.getTypeAtLocation(
    rowProperty.getValueDeclarationOrThrow()
  );

  const rowTypeString = rowType.getText();

  const types: string[] = [];

  types.push(
    `export type ${toTypeName(tableName)} = ${rowTypeString};`,
    ...
  );

  return types;
}

我已经尝试了很多关于我上面发布的变化,但每次我运行我的generate函数时,我都不能让它打印| null,因为这些场景的属性可能是null
使用ts-morph v18。

2uluyalo

2uluyalo1#

打开strictNullChecks编译器选项:

const project = new Project({
  compilerOptions: {
    allowSyntheticDefaultImports: true,
    esModuleInterop: true,
    module: ModuleKind.ESNext,
    target: ScriptTarget.ESNext,
    strictNullChecks: true, // <-- this
  },
});

否则,类型检查器会忽略union类型中的undefined/null,并认为所有类型都不可为空(ts-morph使用与typescript编译器中相同的默认值)。

相关问题