Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A curated list of awesome 🔥 TypeScript Tips 🔥

NotificationsYou must be signed in to change notification settings

jellydn/typescript-tips

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

A curated list of awesome 🔥 TypeScript Tips 🔥

If you enjoy TypeScript and really want to use Typesafe, you can checkawesome-typesafe

Contents

Tips

Matt Pocock

Wes Bos

Erik Rasmussen

Carlos Caballero

Ankita Kulkarni

Minko Gechev

Cory House

Tomek Sułkowski

Sebastien Lorber

Steve (Builder.io)

StackBlitz

Extending existing types

  • PackageJson - There are a lot of tools thatplace extra configurations inside thepackage.json file. You can extendPackageJson to support these additional configurations.

    Example

    Playground

    importtype{PackageJsonasBasePackageJson}from"type-fest";importtype{Linter}from"eslint";typePackageJson=BasePackageJson&{eslintConfig?:Linter.Config};

Built-in types

There are many advanced types most users don't know about.

  • Partial<T> -Make all properties inT optional.

    Example

    Playground

    interfaceNodeConfig{appName:string;port:number;}classNodeAppBuilder{privateconfiguration:NodeConfig={appName:"NodeApp",port:3000,};privateupdateConfig<KeyextendskeyofNodeConfig>(key:Key,value:NodeConfig[Key]){this.configuration[key]=value;}config(config:Partial<NodeConfig>){typeNodeConfigKey=keyofNodeConfig;for(constkeyofObject.keys(config)asNodeConfigKey[]){constupdateValue=config[key];if(updateValue===undefined){continue;}this.updateConfig(key,updateValue);}returnthis;}}// `Partial<NodeConfig>`` allows us to provide only a part of the// NodeConfig interface.newNodeAppBuilder().config({appName:"ToDoApp"});
  • Required<T> -Make all properties inT required.

    Example

    Playground

    interfaceContactForm{email?:string;message?:string;}functionsubmitContactForm(formData:Required<ContactForm>){// Send the form data to the server.}submitContactForm({email:"ex@mple.com",message:"Hi! Could you tell me more about�",});// TypeScript error: missing property 'message'submitContactForm({email:"ex@mple.com",});
  • Readonly<T> -Make all properties inT readonly.

    Example

    Playground

    enumLogLevel{Off,Debug,Error,Fatal,}interfaceLoggerConfig{name:string;level:LogLevel;}classLogger{config:Readonly<LoggerConfig>;constructor({ name, level}:LoggerConfig){this.config={ name, level};Object.freeze(this.config);}}constconfig:LoggerConfig={name:"MyApp",level:LogLevel.Debug,};constlogger=newLogger(config);// TypeScript Error: cannot assign to read-only property.logger.config.level=LogLevel.Error;// We are able to edit config variable as we please.config.level=LogLevel.Error;
  • Pick<T, K> -FromT, pick a set of properties whose keys are in the unionK.

    Example

    Playground

    interfaceArticle{title:string;thumbnail:string;content:string;}// Creates new type out of the `Article` interface composed// from the Articles' two properties: `title` and `thumbnail`.// `ArticlePreview = {title: string; thumbnail: string}`typeArticlePreview=Pick<Article,"title"|"thumbnail">;// Render a list of articles using only title and description.functionrenderArticlePreviews(previews:ArticlePreview[]):HTMLElement{constarticles=document.createElement("div");for(constpreviewofpreviews){// Append preview to the articles.}returnarticles;}constarticles=renderArticlePreviews([{title:"TypeScript tutorial!",thumbnail:"/assets/ts.jpg",},]);
  • Record<K, T> -Construct a type with a set of propertiesK of typeT.

    Example

    Playground

    // Positions of employees in our company.typeMemberPosition="intern"|"developer"|"tech-lead";// Interface describing properties of a single employee.interfaceEmployee{firstName:string;lastName:string;yearsOfExperience:number;}// Create an object that has all possible `MemberPosition` values set as keys.// Those keys will store a collection of Employees of the same position.constteam:Record<MemberPosition,Employee[]>={intern:[],developer:[],"tech-lead":[],};// Our team has decided to help John with his dream of becoming Software Developer.team.intern.push({firstName:"John",lastName:"Doe",yearsOfExperience:0,});// `Record` forces you to initialize all of the property keys.// TypeScript Error: "tech-lead" property is missingconstteamEmpty:Record<MemberPosition,null>={intern:null,developer:null,};
  • Exclude<T, U> -Exclude fromT those types that are assignable toU.

    Example

    Playground

    interfaceServerConfig{port:null|string|number;}typeRequestHandler=(request:Request,response:Response)=>void;// Exclude `null` type from `null | string | number`.// In case the port is equal to `null`, we will use default value.functiongetPortValue(port:Exclude<ServerConfig["port"],null>):number{if(typeofport==="string"){returnparseInt(port,10);}returnport;}functionstartServer(handler:RequestHandler,config:ServerConfig):void{constserver=require("http").createServer(handler);constport=config.port===null ?3000 :getPortValue(config.port);server.listen(port);}
  • Extract<T, U> -Extract fromT those types that are assignable toU.

    Example

    Playground

    declarefunctionuniqueId():number;constID=Symbol("ID");interfacePerson{[ID]:number;name:string;age:number;}// Allows changing the person data as long as the property key is of string type.functionchangePersonData<ObjextendsPerson,KeyextendsExtract<keyofPerson,string>,ValueextendsObj[Key]>(obj:Obj,key:Key,value:Value):void{obj[key]=value;}// Tiny Andrew was born.constandrew={[ID]:uniqueId(),name:"Andrew",age:0,};// Cool, we're fine with that.changePersonData(andrew,"name","Pony");// Goverment didn't like the fact that you wanted to change your identity.changePersonData(andrew,ID,uniqueId());
  • NonNullable<T> -Excludenull andundefined fromT.

    ExampleWorks withstrictNullChecks set totrue.

    Playground

    typePortNumber=string|number|null;/** Part of a class definition that is used to build a server */classServerBuilder{portNumber!:NonNullable<PortNumber>;port(this:ServerBuilder,port:PortNumber):ServerBuilder{if(port==null){this.portNumber=8000;}else{this.portNumber=port;}returnthis;}}constserverBuilder=newServerBuilder();serverBuilder.port("8000")// portNumber = '8000'.port(null)// portNumber =  8000.port(3000);// portNumber =  3000// TypeScript errorserverBuilder.portNumber=null;
  • Parameters<T> -Obtain the parameters of a function type in a tuple.

    Example

    Playground

    functionshuffle(input:any[]):void{// Mutate array randomly changing its' elements indexes.}functioncallNTimes<Fnextends(...args:any[])=>any>(func:Fn,callCount:number){// Type that represents the type of the received function parameters.typeFunctionParameters=Parameters<Fn>;returnfunction(...args:FunctionParameters){for(leti=0;i<callCount;i++){func(...args);}};}constshuffleTwice=callNTimes(shuffle,2);
  • ConstructorParameters<T> -Obtain the parameters of a constructor function type in a tuple.

    Example

    Playground

    classArticleModel{title:string;content?:string;constructor(title:string){this.title=title;}}classInstanceCache<Textendsnew(...args:any[])=>any>{privateClassConstructor:T;privatecache:Map<string,InstanceType<T>>=newMap();constructor(ctr:T){this.ClassConstructor=ctr;}getInstance(...args:ConstructorParameters<T>):InstanceType<T>{consthash=this.calculateArgumentsHash(...args);constexistingInstance=this.cache.get(hash);if(existingInstance!==undefined){returnexistingInstance;}returnnewthis.ClassConstructor(...args);}privatecalculateArgumentsHash(...args:any[]):string{// Calculate hash.return"hash";}}constarticleCache=newInstanceCache(ArticleModel);constamazonArticle=articleCache.getInstance("Amazon forests burining!");
  • ReturnType<T> -Obtain the return type of a function type.

    Example

    Playground

    /** Provides every element of the iterable `iter` into the `callback` function and stores the results in an array. */functionmapIter<Elem,Funcextends(elem:Elem)=>any,RetextendsReturnType<Func>>(iter:Iterable<Elem>,callback:Func):Ret[]{constmapped:Ret[]=[];for(constelemofiter){mapped.push(callback(elem));}returnmapped;}constsetObject:Set<string>=newSet();constmapObject:Map<number,string>=newMap();mapIter(setObject,(value:string)=>value.indexOf("Foo"));// number[]mapIter(mapObject,([key,value]:[number,string])=>{returnkey%2===0 ?value :"Odd";});// string[]
  • InstanceType<T> -Obtain the instance type of a constructor function type.

    Example

    Playground

    classIdleService{doNothing():void{}}classNews{title:string;content:string;constructor(title:string,content:string){this.title=title;this.content=content;}}constinstanceCounter:Map<Function,number>=newMap();interfaceConstructor{new(...args:any[]):any;}// Keep track how many instances of `Constr` constructor have been created.functiongetInstance<ConstrextendsConstructor,ArgsextendsConstructorParameters<Constr>>(constructor:Constr, ...args:Args):InstanceType<Constr>{letcount=instanceCounter.get(constructor)||0;constinstance=newconstructor(...args);instanceCounter.set(constructor,count+1);console.log(`Created${count+1} instances of${Constr.name} class`);returninstance;}constidleService=getInstance(IdleService);// Will log: `Created 1 instances of IdleService class`constnewsEntry=getInstance(News,"New ECMAScript proposals!","Last month...");// Will log: `Created 1 instances of News class`
  • Omit<T, K> -Constructs a type by picking all properties from T and then removing K.

    Example

    Playground

    interfaceAnimal{imageUrl:string;species:string;images:string[];paragraphs:string[];}// Creates new type with all properties of the `Animal` interface// except 'images' and 'paragraphs' properties. We can use this// type to render small hover tooltip for a wiki entry list.typeAnimalShortInfo=Omit<Animal,"images"|"paragraphs">;functionrenderAnimalHoverInfo(animals:AnimalShortInfo[]):HTMLElement{constcontainer=document.createElement("div");// Internal implementation.returncontainer;}
  • Uppercase<S extends string> -Transforms every character in a string into uppercase.

    Example
    typeT=Uppercase<"hello">;// 'HELLO'typeT2=Uppercase<"foo"|"bar">;// 'FOO' | 'BAR'typeT3<Sextendsstring>=Uppercase<`aB${S}`>;typeT4=T3<"xYz">;// 'ABXYZ'typeT5=Uppercase<string>;// stringtypeT6=Uppercase<any>;// anytypeT7=Uppercase<never>;// nevertypeT8=Uppercase<42>;// Error, type 'number' does not satisfy the constraint 'string'
  • Lowercase<S extends string> -Transforms every character in a string into lowercase.

    Example
    typeT=Lowercase<"HELLO">;// 'hello'typeT2=Lowercase<"FOO"|"BAR">;// 'foo' | 'bar'typeT3<Sextendsstring>=Lowercase<`aB${S}`>;typeT4=T3<"xYz">;// 'abxyz'typeT5=Lowercase<string>;// stringtypeT6=Lowercase<any>;// anytypeT7=Lowercase<never>;// nevertypeT8=Lowercase<42>;// Error, type 'number' does not satisfy the constraint 'string'
  • Capitalize<S extends string> -Transforms the first character in a string into uppercase.

    Example
    typeT=Capitalize<"hello">;// 'Hello'typeT2=Capitalize<"foo"|"bar">;// 'Foo' | 'Bar'typeT3<Sextendsstring>=Capitalize<`aB${S}`>;typeT4=T3<"xYz">;// 'ABxYz'typeT5=Capitalize<string>;// stringtypeT6=Capitalize<any>;// anytypeT7=Capitalize<never>;// nevertypeT8=Capitalize<42>;// Error, type 'number' does not satisfy the constraint 'string'
  • Uncapitalize<S extends string> -Transforms the first character in a string into lowercase.

    Example
    typeT=Uncapitalize<"Hello">;// 'hello'typeT2=Uncapitalize<"Foo"|"Bar">;// 'foo' | 'bar'typeT3<Sextendsstring>=Uncapitalize<`AB${S}`>;typeT4=T3<"xYz">;// 'aBxYz'typeT5=Uncapitalize<string>;// stringtypeT6=Uncapitalize<any>;// anytypeT7=Uncapitalize<never>;// nevertypeT8=Uncapitalize<42>;// Error, type 'number' does not satisfy the constraint 'string'

You can find some examples in theTypeScript docs.

Contribute

Contributions welcome! Read thecontribution guidelinesfirst.

Twitter to markdown file

Create .envrc and fill the value then Usetweet-to-markdown

# .envrcexport TTM_API_KEY=YOUR_API_KEY

Then run thedirenv command

 direnv allow.

And, generate markdown from a twitter url

npx tweet-to-markdown -p notes https://twitter.com/mattpocockuk/status/1509964736275927042\?s\=20\&t\=sA-g5MNM5TPjN6Ozs1qxgA

Then save video if available

npx twt-dl-cli@latest https://twitter.com/mattpocockuk/status/1592130978234900484

Finally, add theThread Reader App at the end with below format.

[Thread by@USERNAME on Threadify Reader App](https://threadify.productsway.com/thread/STATUS_ID)

NOTE: I have sent a pull request about this step totweet-to-markdown repository:feat: add Thread Reader App link and the end #19 Might not need this step if this PR is accepted.

Credits

This project is made by community and especially the wonderful people and projects listed in this document

Open Source

Tech Twitter

Author

👤Huynh Duc Dung

Show your support

Give a ⭐️ if this project helped you!

kofipaypalbuymeacoffee

Stargazers over time

Stargazers over time

About

A curated list of awesome 🔥 TypeScript Tips 🔥

Topics

Resources

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors3

  •  
  •  
  •  

[8]ページ先頭

©2009-2025 Movatter.jp