45 votes

Quelle est la différence entre le type générique (T) et tout type tapuscrit

Quelle est la différence entre generic Type(T) vs any dans le tapuscrit?

Fonction 1

function identity(arg: any): any {
    return arg;
}

Fonction 2

function identity<T>(arg: T): T {
    return arg;
}

Fonction 3

function identity<T>(arg: T[]): T[] {
    return arg;
}

La fonction 1 & 3 est acceptée si nous passer toute sorte d' data type, Mais la fonction 2 n'accepte pas si on passe un array. type générique est d'accepter tous les types de type de données sur le temps de compilation. mais ici, pourquoi ne pas accepter?

Aussi la fonction qui est bon pour de meilleures performances ( fonction 1 fonction ou 3)?

35voto

estus Points 5252

Il n'y a pas de différence si ce n'est l'identité de la fonction qui retourne juste un argument et utilisés sans restrictions de type:

const foo: any = fn(['whatever']);

Et il y a une différence de tapé le code:

const foo: string = fn('ok');
const bar: string = fn([{ not: 'ok' }]);

Aussi, l'utilisation de type générique fournit la sémantique. Cette signature suggère que la fonction est non typé et renvoie rien:

function fn(arg: any): any { ... }

Cette signature suggère que la fonction renvoie le même type de son argument:

function fn<T>(arg: T): T { ... }

Fonctions réelles sont généralement plus utile que juste return arg exemple. Type générique peut bénéficier de type de restrictions (tout en any ne peuvent évidemment pas):

function fn<T>(arg: T[]): T[] {
  return arg.map((v, i) => arg[i - 1]);
}

Mais les avantages à devenir plus évident lorsque la fonction est utilisée en conjonction avec d'autres classes génériques et les fonctions génériques (et éliminé en cas de non-génériques sont impliqués):

function fn<T>(arg: T[]): T[] {
  return Array.from(new Set<T>(arg));
}

Cela permet de maintenir constamment T type entre l'entrée (argument) et de sortie (valeur de retour):

const foo: string[] = fn(['ok']);
const bar: string[] = fn([{ not: 'ok' }]);

Il ne peut y avoir aucune différence dans les performances, car Tapuscrit types n'existent que sur le moment de la conception.

25voto

Milad Points 12206

Il n'y a absolument aucune différence de performances tout en utilisant une de ces méthodes, parce que toutes ces choses de fantaisie sont juste Typescript sucres, et est seulement pour le développement.

Tous les type de vérification est seulement au moment de la compilation ( lorsque la Machine est transpiling/transformation de votre code de retour à la normale javascript dans votre serveur ).

De toute façon, lorsque votre code est envoyé au navigateur de l'utilisateur, c'est à quoi il ressemble :

function identity(arg){
    return arg;
}

Mais pour expliquer les différences :

Lors de l'utilisation d' any vous perdrez tous type de vérification et de vérification de la sécurité que Tapuscrit est d'offrir, alors que, T se comporte comme une variable qui va contenir le Type que vous ne savez pas ce que ça va être.

Donc

function identity<T>(arg: T): T {
    return arg;
}

Ci-dessus, nous savons que si l' identify accepte number , il sera de retour number et ainsi de suite, où que :


function identity(arg: any): any {
    return arg;
}

Mais maintenant, vous ne savez pas si arg et de la returned de la valeur du même type ou non.


L'autre question qu' T permettra de résoudre, c'est quand vous êtes en train de créer une méthode à l'intérieur d'une classe et il attend un argument qui vous voulez vous assurer que cette méthode ne pourra accepter des arguments du même type de constructeur de la classe de l'argument lorsqu'il est instancié.

export class MyClass<T>{

   myMethod(anotherArg:T){}

}

Donc, en utilisant ci-dessus :

let str = "string";
let instance = new MyClass(str);
instance.myMethod("other string") // will compile

Où que :

let num = 32423423;
let instance = new MyClass(num);
instance.myMethod("other string") // won't compile

3voto

Supamiu Points 5927

La principale utilisation de l' T pour éviter de casser le type lorsque vous appelez une méthode.

Exemple:

Si vous ne :

let foo = new Foo();
identity(foo).bar();

La deuxième ligne sera ok pour le compilateur, mais pas parce qu'il sait qu' bar existe en Foo type, parce que c'est any, et any peut avoir n'importe quelle méthode.

Si vous ne :

let foo = new Foo();
identity<Foo>(foo).bar();
identity<Foo>(foo).notExistingMethod();

La deuxième ligne sera de compiler fine, non pas la troisième parce qu' Foo n'ont pas d' notExistingMethod méthode.

tout est souvent utilisé lorsque vous avez besoin de créer quelque chose de plus Javascript-chemin, ce qui signifie que vous ne savez pas vraiment ce qui est dans votre objet, depuis Javascript n'est pas de tout types (je ne parle pas de l' es6 ofc).

2voto

Murat Karagöz Points 13113

Tout est any sur l'exécution et sur le dessus de qui il est any au moment de la compilation en JavaScript. C'est pourquoi il est TypeScript de fournir le type de sécurité au moment de la compilation.

La différence entre any et T / T extends etc. c'est que vous avez un type de la sécurité au cours de la compilation, par exemple

protected typeSafety = <T extends String>(args:T):T =>{
    return args;
}

this.typeSafety(1); // compile error
this.typeSafety("string"); // good to go

Si la fonction accepte tout ce que vous avez l'erreur lors de l'exécution, ce qui serait trop tard.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X