typescript-notes

Typescript Notes

Typescript


Neden ortaya çıktı?


Neden ihtiyaç duyuyoruz?


Static Typing & Dynamic Typing

let a = 5;
a = "Dynamic typing";
const a = 5;
a = "Dynamic typing";
//a değişkenini const ile tanınmladığımız için burada hata fırlatması lazım.
//Ama bu hatayı runtime da veriyor.
let a: number = 5;
a = "Dynamic typing";
// burada bize ts den ötürü hata fırlatıyor.
//Type ı number olan bir değişkene sen string atayamazsın şeklinde daha compile aşamasında bana hata veriyor.

jsvsts


Typescript avantajları;

Note: Tarayıcılar Typescript kodunu anlayamazlar. Bu yüzden bir derleyici yardımı ile TS kodu Js koduna dönüştürülür. (tsc=> typescript compiler)


Ne zaman kullanılmalı?

//ts kodu

const a = "anthony";

const myName = `Name: ${a}`;

// js kodu

var a = "anthony";
var myName = "Name: ".concat(a);
// es5 te const olmadığı için var olarak compile etti.
//yine template string olmadığı için de diğer bir yöntem olan concat ı kullandı.

Pure typescript de targetı es5 olarak ayarlayıp Spread operatörünü deneyebilirsiniz:).


TS Types

let x;
x="merhaba";
burada x in type ını ts any olarak atıyor.

Eğer değişkeni declare edip değerini sonra atayacaksak ve any tipinde olmasını istemiyorsak tanımladığımız yerde @typeannotations :type kullanarak tipini de declare edebiliriz:

let x:string;
x="merhaba";
burada x in type ını string olarak belirlemiş olduk.

Ama değişkene değerini declare ederken değerinide vereceksek @typeannotations kullanmamıza gerek yok. Typescript değerin tipine göre değişkenimizin typeını belirliyor. TYPE INFERENCE

let x: string = "merhaba"; //yani buradaki işleme gerek yok
let y = "dünya";
//x vey yi ts string olarak belirliyor
let x: string = "merhaba";
let y = "dünya"; //Type Inference
// x ve y değişkenlerine artık sadece string veri tipinde bir değer ataması yapabiliriz.
let x: number = 67;
let y = 60.5; //Type Inference
// x ve y değişkenlerine artık sadece number veri tipinde bir değer ataması yapabiliriz.
let x: boolean = false;
let y = true; //Type Inference
// x ve y değişkenlerine artık sadece boolean veri tipinde bir değer ataması yapabiliriz.
    let myArr: string[] = ["a","b","c"] //bu arraye atayacağınız elemanların hepsi string tipli olmalıdır.
    let myArr1:number[] = [1,2,3] //bu arraye atayacağınız elemanların hepsi number tipli olmalıdır.
    et myArr1:Array<number> = [1,2,3] //bu şekilde de arraylerde type tanımlaması yapabiliyoruz. Ama en yaygın kullanım diğer örneklerdeki gibi olan kullanım.
    let myAnyArr : any[] = ["a",1,true] //bu arraye atayacağınız elemanlar farklı tiplerde olabilir. any diyerek aslında javascript arraye dönüştürmüş olduk.

let myArr: [string, number] = ["error", 25];
myArr = [285, 285]; // error
myArr = [34, "istanbul"]; // error
myArr = ["istanbul", 34]; // doğru kullanım
let a = "anthony";

let myName = `Name: ${a}`;

let x: any = 5;

a = x;

let y: unknown = 5;

myName = y; // Type 'unknown' is not assignable to type 'string'.
let todo = {
  task: "deneme 1",
  description: "deneme 1 deneme 1",
  is_done: "false",
};
//bu şekilde tanımlama yaptığımzıda ts typeları belirliyor. ama diyelim değerlerimiz belli değil sadece değişkeni declare edeceğiz o zaman da:
let todo: {
  task: string;
  description: string;
  is_done: boolean;
};
todo = {
  task: "deneme 1",
  description: "deneme 1 deneme 1",
  is_done: "false",
}; // todo objesi sadece belirlediğimiz keyleri alabilir. Ve onlarında typeı yine sadece belirlenen tiplerde olur.

// Şimdilik bu şekilde objeyi declare edip tipini obje şeklinde verebiliriz. Ilerleyen aşamalarda obje tanımlamada en çok kullandığımız interfaceleri göreceğiz. Tabi ki type aliases ile de tanımlama yapabiliriz.
let todo: {
  task: string;
  description: string;
  is_done: boolean;
  count: string | number;
};
todo = {
  task: "deneme 1",
  description: "deneme 1 deneme 1",
  is_done: "false",
  count: 5,
};
todo.count = "5"; // hem number hem string değer atayabildik. Union type kullanarak `|` hata vermesinin önüne geçebildik.
let todo: {
  task: string;
  description: string;
  is_done: boolean;
  category: "work" | "travel";
};
todo.category = "enjoy"; // hata atar
todo.category = "work"; //kabul eder
todo.category = "travel"; //kabul eder
type Todo = {
  task: string;
  description: string;
  is_done: boolean;
};
let todo: Todo = {
  task: "deneme 1",
  description: "deneme 1 deneme 1",
  is_done: "false",
};

// custom typelı array
let todos: Todo[] = [
  {
    task: "deneme 1",
    description: "deneme 1 deneme 1",
    is_done: "false",
  },
  {
    task: "deneme 2",
    description: "deneme 2 deneme 2",
    is_done: "false",
  },
];

Custom typelar compile edildiğinde js dosyadında yer almazlar. Typescripte özeldirler.

void : Bir şeyi yapmasını istediğimiz methodlara void operasyon denir. Örneğin veritabanına veri ekle gibi. Emir kipi gibi düşünülebilir.Herhangi bir veri döndürmezler.

const myfunc = (num1: number, num2: number): number => {
  return num1 + num2;
};
//void
const myfuncs = (num1: number, num2: number): void => {
  console.log(num1 + num2);
};

//Type Inference
const myfunc = (num1: number, num2: number) => {
  return num1 + num2;
};
//void
const myfunc = (num1: number, num2: number) => {
  console.log(num1 + num2);
};
type Todo = {
  task: string;
  description?: string; //description olsa da olur olmasada olur diyoruz.
  is_done: boolean;
};
let todo: Todo = {
  task: "deneme 1",
  description: "deneme 1 deneme 1",
  is_done: "false",
};
let todo2: Todo = {
  task: "deneme 1",
  is_done: "false",
};
// iki tanımlamada başarılı bir şekilde gerçekleşir.
interface Course {
  title: string;
  description: string;
  createdAt: Date;
  updatedAt: Date;
  price: number;
  currency: string;
  isActive: boolean;
}
const webCourse: Course = {
  title: "Typescript Basics",
  description: "A course about Typescript",
  createdAt: new Date(),
  updatedAt: new Date(),
  price: 1500,
  currency: "USD",
  isActive: true,
};
interface Course {
  title: string;
  description: string;
  createdAt: Date;
  updatedAt: Date;
  price?: number; //Optional
  currency: string | undefined; //Optional
  isActive: boolean;
}
const webCourse: Course = {
  title: "Typescript Basics",
  description: "A course about Typescript",
  createdAt: new Date(),
  updatedAt: new Date(),
  isActive: true,
};
interface Course {
  title: string;
  description: string;
  createdAt: Date;
  updatedAt: Date;
  price?: number; //Optional
  currency: string | undefined; //Optional
  isActive: boolean;
}
interface NewCourse extend Course {
    instructor:string
}
let mycourse: NewCourse = {
  title: "Typescript Plus",
  description: "A course about Typescript",
  createdAt: new Date(),
  updatedAt: new Date(),
  price: 2000,
  currency: "USD",
  isActive: true,
  instructor: "anthony",
};

//Burada görebileceğiniz gibi, bir NewCourse ve Course tanımladık. NewCourse, Course interface’ini kullanmamıza izin verir.
interface Course {
  readonly title: string; //Read only
  description: string;
  createdAt: Date;
  updatedAt: Date;
  price?: number; //Optional
  currency: string | undefined; //Optional
  isActive: boolean;
}
interface FootballCourse extends Course {
  coach: string;
}

Aşağıdaki kullanım hata verecektir:

const webCourse: FootballCourse = {
  title: "Typescript Basics",
  description: "A course about Typescript",
  createdAt: new Date(),
  updatedAt: new Date(),
  isActive: true,
  coach: "Nicky Christensen",
};
webCourse.title = "A new title"; //ERROR. Çünkü readonly field oalrak tanımladık. İlk atamadaki değeri alır onu korur.

GENERICS

interface auth {
  id: number;
  username: string;
}

interface Category {
  id: number;
  title: string;
}

interface Post {
  id: number;
  title: string;
  desc: string;
  exttra: auth[] | Category[];
}
///Buraya kadar bildiiğimiz İnterface
interface PostBetter<T> {
  id: number;
  title: string;
  extra: T[];
}
//Burada <T> ile gördüğünüz bize bir parametre döndürmemizi istiyor >> Type Parameter
const testGenerics: PostBetter<String> = {
  // Burada o Beklediği Type Parametreyi giriyoruz <String> olarak
  id: 1,
  title: "Big Titlle",
  extra: ["extra1", "extra2"], // Burada tanımlamamız bu şekilde
};

interface UpgradePostWithObject<T extends Object> {
  id: number;
  title: string;
  extra: T[];
}

const test2Generics: UpgradePostWithObject<{ id: number; username: string }> = {
  id: 1,
  title: "Big Titlle",
  extra: [{ id: 1, username: "taha" }],
}; // Burada Obje çağırdık çüngü UpgradePotWithObject interface kısmıbnda T nin üzerine  bir de obje ekle dedik

Type Assertions

let myAge;
myAge = 29;
const newAge = (<string>myAge).toLowerCase();
const newAge2 = (myAge as string).toLowerCase();
//tsyi susturyoruz ama runtime aşamasında hata döner.çünkü numberın toLowerCase metodu yoktur.

Pure Typescript Projesi Oluşturma Komutları

`npx tsc --init`
# bu komutla birlikte tsconfig.json dosyası oluşur. Sonrasında app.ts de yazdığımız kodların js e dönüşmesi için aşağıdaki komutu gireriz:
`tsc app.ts`
# Bu komutton sonra bize otomatik olarak aynı isimde js dosyası oluşturur. Biz index.html e oluşan app.js dosyasını bağlamamız gerekir.her yeni işlemde terminale girmem gerekiyor.

`tsc app.ts -w`
# watch moduna alıp her yaptığım işlemi anında compile eder.

React Typescript

Start Project CRA

npx create-react-app todo-ts --template typescript

#or

yarn create react-app todo-ts --template typescript

CRA ile Proje Oluşturma


Start Project Vite

Command => pnpm create vite or yarn create vite
Framework => React
Variant => Typescript

# or

pnpm create vite todoapp --template react-ts

Vite ile Proje Oluşturma


React Types

function Card(props: { children: React.ReactNode }) {
  return <button>{props.children}</button>;
}
// interface de kullanabiliriz
type CardProps = {
  title: string;
};

function Card(props: CardProps) {
  return <h1>{props.title}</h1>;
}

// with destructuring
function Card({ title }: ButtonProps) {
  return <h1>{title}</h1>;
}
interface ICardProps = {
  disabled?: boolean;
  title: string;
};

function Card({ disabled = true, title }: ICardProps) {
  return (
    <div disabled={disabled}>
      <h1>{title}</h1>
      <button disabled={disabled}>Change</button>
    </div>
  );
}
import React from "react";

interface ICardProps = {
  disabled?: boolean;
  title: string;
};
const Card:React.FC<ICardProps> = ({ disabled = true, title }) => {
  return (
    <div disabled={disabled}>
      <h1>{title}</h1>
      <button disabled={disabled}>Change</button>
    </div>
  );
}
// ❌ Typescript her zaman initial değere string atadığınızda o statein string olduğunu bilir.
const [text, setText] = useState<string>("");
// ✅ Type Inference sayesinde primitive typelarda initia değer verdiğimizde type tanımlamıza ihtiyaç yok.
const [text, setText] = useState("");

type Todo = {
  id: number;
  text: string;
};
// ama non-primitive typelarda initial değere boş array veya obje verdiğimizde typeı tanımlamalıyız.
const [todos, setTodos] = useState<Todo[]>([]);

const [todos, setTodos] = useState<Todo[] | null>(null);
export const AddTodo = () => {
  // initial değer varsa type tanımlamaya gerek yok
  const myRef = useRef("");
  // initial değer yoksa type tanımlamlanır
  const yourRef = useRef<string>();

  useEffect(() => {
    myRef.current = "Random value!";
    yourRef.current = "Random value!";
  }, []);

  return <div></div>;
};
// HTML elementleri ile kullanım

export const AddTodo = () => {
  // hangi elemente tanımlayacaksak onu belirtiyoruz. İnitial değere de null atıyoruz.
  const inputRef = useRef<HTMLInputElement>(null);

  return <input ref={inputRef} />;
};
//ThemeContext.ts
import React,{ createContext, useState,useContext } from "react";

type ThemeContextType = "light" | "dark";

const ThemeContext = createContext<ThemeContextType | null>("light");

const ThemeContextProvider: React.FC = ({ children }:React.ReactNode) => {
  const [myTheme, setMyTheme] = useState<ThemeContextType>("light");

  return (
    <ThemeContext.Provider value=>
      {children}
    </ThemeContext.Provider>
  );
};


export const useThemeContext = () => {
    return useContext(ThemeContext)
}

//index.tsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import ThemeContextProvider from './context/ThemeContext';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <ThemeContextProvider>
    <App />
  </ThemeContextProvider>
);

//App.tsx

import { useThemeContext } from "./context/ThemeContext";
const App = () => {
  const {myTheme} = useThemeContext();
  return <p>current theme: {myTheme}</p>;
};

Redux Toolkit Dökümanından ayrıntılı inceleyebilirsiniz.

//input-form examples
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
onFocus: (event: FocusEvent<HTMLInputElement>) => void;
onBlur: (event: FocusEvent<HTMLInputElement>) => void;

//button-div examples
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
onDoubleClick: (event: MouseEvent<HTMLDivElement>) => void;
onMouseEnter: (event: MouseEvent<HTMLButtonElement>) => void;
onMouseLeave: (event: MouseEvent<HTMLButtonElement>) => void;

Type ları globalde tanımlama


Typescript Cheat Sheet

Typescript Cheat Sheet