function resolveTableAddColumn()

in server/src/standardLibrary/standardLibraryTypeResolver.ts [56:97]


function resolveTableAddColumn(args: ReadonlyArray<Type.TPowerQueryType>): Type.TPowerQueryType | undefined {
    const table: Type.TPowerQueryType = TypeUtils.assertAsTable(PQP.Assert.asDefined(args[0]));
    const columnName: Type.TText = TypeUtils.assertAsText(PQP.Assert.asDefined(args[1]));
    const columnGenerator: Type.TFunction = TypeUtils.assertAsFunction(PQP.Assert.asDefined(args[2]));
    const maybeColumnType: Type.TPowerQueryType | undefined =
        args.length === 4 ? TypeUtils.assertAsType(PQP.Assert.asDefined(args[3])) : undefined;

    // We can't mutate the given table without being able to resolve columnName to a literal.
    if (!TypeUtils.isTextLiteral(columnName)) {
        return undefined;
    }

    let columnType: Type.TPowerQueryType;
    if (maybeColumnType !== undefined) {
        columnType = maybeColumnType;
    } else if (TypeUtils.isDefinedFunction(columnGenerator)) {
        columnType = columnGenerator.returnType;
    } else {
        columnType = Type.AnyInstance;
    }

    const normalizedColumnName: string = PQP.Language.TextUtils.normalizeIdentifier(columnName.literal.slice(1, -1));

    if (TypeUtils.isDefinedTable(table)) {
        // We can't overwrite an existing key.
        if (table.fields.has(normalizedColumnName)) {
            return Type.NoneInstance;
        }

        return TypeUtils.createDefinedTable(
            table.isNullable,
            new PQP.OrderedMap([...table.fields.entries(), [normalizedColumnName, columnType]]),
            table.isOpen,
        );
    } else {
        return TypeUtils.createDefinedTable(
            table.isNullable,
            new PQP.OrderedMap([[normalizedColumnName, columnType]]),
            true,
        );
    }
}