Código final

Y este código al que hemos llegado

let
    url = "https://interactivechaos.com/data/curso_m/dataset.xlsx",
    file = Web.Contents(url),
    tables = Excel.Workbook(file),
    geography = tables{[Item="Geography",Kind="Sheet"]}[Data],
    encabezados = Table.PromoteHeaders(geography),
    tipos = Table.TransformColumnTypes(
        encabezados,
        {
            {"Geography Id", Int64.Type},
            {"Country", type text},
            {"Region", type text},
            {"City", type text}
        }
    )
in
    tipos

lee y transforma la tabla con información geográfica del libro Excel de idéntica forma a como lo hace el proceso ETL correspondiente a la consulta Geography generado automáticamente por el editor de consultas:

let
    Origen = Excel.Workbook(Web.Contents("https://interactivechaos.com/data/curso_m/dataset.xlsx"), null, true),
    Geography_Sheet = Origen{[Item="Geography",Kind="Sheet"]}[Data],
    #"Encabezados promovidos" = Table.PromoteHeaders(Geography_Sheet, [PromoteAllScalars=true]),
    #"Tipo cambiado" = Table.TransformColumnTypes(#"Encabezados promovidos",{{"Geography Id", Int64.Type}, {"Country", type text}, {"Region", type text}, {"City", type text}})
in
    #"Tipo cambiado"

Aparte del hecho de que nosotros hemos separado la última fórmula de paso en varias líneas (lo que no tiene impacto alguno en el rendimiento del código), la única diferencia destacable entre nuestro código y el generado automáticamente por el editor de consultas reside en el hecho de que nuestras primeras tres fórmulas de código

    url = "https://interactivechaos.com/data/curso_m/dataset.xlsx",
    file = Web.Contents(url),
    tables = Excel.Workbook(file),

se ejecutan en una única línea en el código generado por el editor:

Origen = Excel.Workbook(Web.Contents("https://interactivechaos.com/data/curso_m/dataset.xlsx"), null, true),

(olvidémonos por ahora de los argumentos adicionales que vemos pasados a la función Excel.Workbook: null y true)

En el código generado por el editor de consultas la url se pasa directamente como texto a la función Web.Contents, y el resultado de esto se pasa directamente como argumento de la función Excel.Workbook. Si quisiéramos que nuestro código tuviese esta misma estructura debería ser rescrito de la siguiente forma:

let
    tables = Excel.Workbook(Web.Contents("https://interactivechaos.com/data/curso_m/dataset.xlsx")),
    geography = tables{[Item="Geography",Kind="Sheet"]}[Data],
    encabezados = Table.PromoteHeaders(geography),
    tipos = Table.TransformColumnTypes(
        encabezados,
        {
            {"Geography Id", Int64.Type},
            {"Country", type text},
            {"Region", type text},
            {"City", type text}
        }
    )
in
    tipos

Con independencia de esto, vemos que la escritura desde cero de un sencillo proceso ETL como éste no es algo complejo y, de hecho, nos permite entender mucho mejor cómo funciona el lenguaje M.