web-dev-qa-db-fra.com

Qu'est-ce que "type '{}'"?

Dans TypeScript, quelle est exactement type '{}' et comment est-ce lié aux autres types intégrés?

Par exemple, la dernière ligne de l'exemple suivant donne Type '{}' is not assignable to type 'number', et je ne sais pas exactement ce que type {} se situe dans ce contexte, ou bien comment cela se produit:

// A function taking no arguments and returning T
type NoArgsFn<T> = () => T;

// An instance of NoArgsFn<number>
function get_the_answer(): number {
  return 42;
}

// Call the supplied function and return its value
function call<T, Fn extends NoArgsFn<T>>(fn: Fn): T {
  return fn();
}

// Expect this to be equivalent to `let the_answer: number = 42', but
// instead get "Type '{}' is not assignable to type 'number'"
let the_answer: number = call(get_the_answer);
20
NPE

type {}

Considérez le type d'objet { id: number, name: string }, qui représente un objet à 2 champs. Les valeurs légales de ce type incluent { id: 1, name: "Foo" } et { id: 2, name: "Bar" }.

L'objet type {} représente un objet à 0 champ. La valeur légale uniquement de ce type est un objet vide: {}.

Donc la valeur -{ id: 1, name: "Foo" } est de type{ id: number, name: string }, et la valeur {} (c'est-à-dire un objet vide) est de type{}.

L'erreur

L'erreur semble être un bogue dans le compilateur TypeScript (j'ai soumis un problème ici ). Il ne parvient pas à déduire les arguments de type dans l'appel à call. Vous pouvez contourner cela en spécifiant explicitement les arguments de type:

let the_answer: number = call<number, NoArgsFn<number>>(get_the_answer);

Mais il est plus simple et plus simple d'utiliser un argument de type unique à la place, comme l'a suggéré @NitzanTomer:

function call<T>(fn: NoArgsFn<T>): T {
  return fn();
}

EDIT: Le problème que j'ai soumis a été fermé en tant que doublon # 7234 qui doit être corrigé avant la sortie de TypeScript 2.0 .

15
Spike

Vous devez avoir votre fonction d'appel comme ceci:

function call<T>(fn: NoArgsFn<T>): T {
    return fn();
}

Dans votre fonction call d'origine, vous aviez 2 types génériques que vous n'avez pas transmis lors de l'appel de la fonction et le compilateur n'a pas pu en déduire de quels types il s'agit.


Éditer

Tapez {} est un objet littéral (pour autant que je sache), et vous pouvez donc faire face à la même erreur comme ceci:

var o = {};
var n: number = o; // Error: Type '{}' is not assignable to type 'number'

Je ne sais pas exactement pourquoi le compilateur a déduit que la fonction renvoie {} dans votre exemple.

5
Nitzan Tomer

Pour autant que je sache, {} effectue une conversion directe vers une carte de hachage comme l'utilisation. Vous ne pouvez utiliser que des propriétés à clé, contrairement à la notation par points.

var o:{} = {}

devrait être équivalent à

var o:{[key:string]:any} = {}

Alors

o.x = 5; //fails

Mais

o['x'] = 5; //succeeds
4
ArcSine