Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

344
Visualizações
Property 'foo' does not exist on type '{}' when using new Proxy({}), .....)

I'm not using typescript (and, right now I don't intend to) but the default set up for VSCode seems to have put some checking in for me. It's kind of handy, kind of a pain. I want to stick with it for now.

My code that causes this issue is:

  let {
    localApiVersion, localDate, remoteVersion, remoteDate,
  } = new Proxy({}, { get: () => null });

Which I took from my answer here. I'm doing this because I didn't feel like doing let localApiVersion = null four times.

However VSCode is giving me this error:

Property 'localApiVersion' does not exist on type '{}'.ts(2339)

The check (I think) is because my jscongig.json looks like this:

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es2019",
        "checkJs": true
    },
    "exclude": [
        "node_modules",
        "**/node_modules/*"
    ]
}

I know I can write // @ts-ignore above that line, but don't want to get into that habit.

Is there a way, without removing the check (or adding typescript to the project), to inform VSCode that these are ok?

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Here is what worked for me (please upvote the other answers too, they were instrumental in me getting here):

  let {
    localApiVersion, localDate, remoteVersion, remoteDate,
  } = /** @type {Object.<string, (null|string)>} */ (new Proxy({}, { get: () => null }));

Note the @type annotation goes before the new and the whole constructor part is wrapped in parens. I'm using (null|string) instead of unknown a) because I know it will be reassigned to a string and b) so I still get some type checking, even though before reassignment you can make type mistakes. I may switch it to just null, and when changing type explicitly use this sort of thing: @type {string} (localApiVersion).

And here is with the tool tip in VSCode:

tooltip on highlighting 'localApiVersion' which reads: let localApiVersion: string

Using typedef will also work:

  /**
   * @typedef {Object.<string, (null|string)>} InitProxy
   */

  let {
    localApiVersion, localDate, remoteVersion, remoteDate,
  } = /** @type {InitProxy} */ (new Proxy({}, { get: () => null }));

But this is getting into the levels of verbosity I'm trying to avoid.

about 4 years ago · Juan Pablo Isaza Relatório

0

The {} type comes from T extends object constraint in ProxyConstructor; in the absence of an explicit type, T is resolved to an empty object, or {}.

However, {} does not fit the bill, since it doesn't have any properties, while your code requires it to have localApiVersion, localDate, etc. Yes, JavaScript knows about these properties (or rather it doesn't care), but TypeScript doesn't know about them, and it cannot communicate with runtime code.

The solution is to type-cast at least something in this picture, so that TypeScript can infer the correct typings. In a .ts file it is trivial. In a .js file, however, this is what can be done:

// @ts-check

/** @type {Record<string, unknown>} */
const target = {};

let { foo, bar, baz } = new Proxy(target, { get: () => null });
about 4 years ago · Juan Pablo Isaza Relatório

0

It seems quite surprising you're getting a TypeScript error on JavaScript code, but you can provide type information via JSDoc annotations (see here, here, and here), which are just comments so they don't require using the TypeScript compiler before running the code in a JavaScript environment.

Having said that, I just cannot get it working with JSDoc annotations. I would expect this to work, because the third link above says you can do type assertions this way:

// @ts-check

/**
 * @typedef {Object} Stuff - comment here
 * @property {any} localApiVersion - comment here
 * @property {any} localDate - comment here
 * @property {any} remoteVersion - comment here
 * @property {any} remoteDate - comment here
 */

let {
    localApiVersion, localDate, remoteVersion, remoteDate,
} = new Proxy(/** @type {Stuff} */ {}, { get: () => null });;

But that doesn't work. :-(

Just for what it's worth, this is easy in TypeScript itself:

interface Stuff {
    localApiVersion: any;
    localDate: any;
    remoteVersion: any;
    remoteDate: any;
}

let {
    localApiVersion, localDate, remoteVersion, remoteDate,
} = new Proxy({} as Stuff, { get: () => null });
//               ^^^^^^^^−−−−−−− type assertion
// I normally avoid type assertions, but this use of the Proxy with get
// trap is a very special case.

(Example on the TypeScript playground.)

I would expect it to be possible with JSDoc annotations, since I know people use TypeScript type checking that way, but, well, I just use TypeScript and haven't been able to figure out a JSDoc equivalent.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda