728x90
728x90


Type System

     ㄴ 컴파일러에게 사용하는 타입을 명시적으로 지정하는 시스템

     ㄴ 컴파일러가 자동으로 타입을 추론하는 시스템


  ◽ Structural과 Nominal Type System

    ◾ Structural : 구조가 같으면 같은 타입 (TypeScript)

    ◾ Nominal : 구조가 같아도 이름이 다르면 다른 타입 (c언어,java)

 

  ◽ Type System of TypeScript

    ◾ 타입을 명시적으로 지정 가능

    ◾ 그렇지 않으면, typescript compiler가 자동으로 타입 추론

 

  ◽ Type

    ◾ 해당 변수가 할 수 있는 일을 결정

 

*duck typing

런타임에 발생하는 타이핑 방식 (파이썬)

If it walks like a duck and it quacks like a duck, then it must be a duck

 

 


옵션 ✔


nolmplicitAny 옵션

타입을 명시적으로 지정하지 않은 경우 typescript가 타입 추론 중 any라고 판단하게 되면 compile error 발생해 타입을 명시적으로 지정하도록 유도한다.

error!! Parameter '00' implicitly has an 'any' type.

sctrictNullChecks 옵션

모든 타입에 자동으로 포함되어 있는 nullundefined를 제거해준다. 

nolmplicitReturns 옵션

함수 내 모든 코드가 값을 리턴하지 않으면 complie error 발생

strictFunctiontypes 옵션

함수를 할당할 시 함수의 매개변수 타입이 같거나 슈퍼타입인 경우가 아니면 에러 발생 (변병)

 

 

 


타입 호환성 Type Compatibility 


sub타입과 super타입

1 number  
number[] object  
[number, number] number[]  
number  any <->
never  number  
A extends B    A는 B에 상속

 

공변 📌

  ◽ primitive type : 같거나 sub타입이면 할당이 가능하다.

  ◽ object, array: 각각의 property가 대응하는 property와 같거나 sub타입이어야 한다.

let sub: string = '';
let sup: string | number = sub;
//
let sub: { a: string; b: number } = { a: '', b: 1};
let sup: { a: string | number; b: number } = sub;
//
let sub: Array<{ a: string; b: number }> = { a: '', b: 1};
let sup: Array<{ a: string | number; b: number }> = sub;

 

변병 📌

  ◽ 함수의 매개변수 타입만 같거나 super타입인 경우 할당이 가능하다.

class Person {}
class Developer extends Person {
  coding() {}
}
class StartupDeveloper extends Developer {
  burning() {}
}

function tellme(f: (d: Developer) => Developer) {}

// Developer => Developer 에다가 Developer => Developer 를 할당하는 경우
tellme(function dToD(d: Developer): Developer {
  return new Developer();
});

// Developer => Developer 에다가 Person => Developer 를 할당하는 경우
tellme(function pToD(d: Person): Developer {
  return new Developer();
});

// Developer => Developer 에다가 StartipDeveloper => Developer 를 할당하는 경우
tellme(function sToD(d: StartupDeveloper): Developer {
  return new Developer();
});

 

 


타입 별칭 type alias 


  ◽ interface랑 유사함

  ◽ primitive, union type, tuple, function

  ◽ 만들어진 타입의 refer(별명)로 사용, 타입을 만드는 개념이 아님

let person: string | number = 0;
person = 'Mark';

type StringOrNumber = string | number;

let another: StringOrNumber = 0;
another = 'Anna';

  ◽ 반복되어 사용될 때 유용

type EatType = (food: string) => void;

 

 


Type


1. Boolean

let isDone: boolean = false;

 

2. String

(큰 따옴표나 작은 따옴표)

let name: string = "Lenord";

2-1. Template String

행에 걸쳐 있거나 표현식을 넣을 수 있는 문자열은 백틱 기호를 사용한다. 그 안에 포함된 표현식은 ${expr}와 같은 형태를 사용한다. 

let fullName: string = "siot";
let sentence: string = ` hello
my name is ${fullName}.` // hello my name is siot.

 

3. Symbol

  • ECMAScript2015에 추가
  • new Symbol로 사용할 수 없다.
  • Symbol을 함수로 사용해서 symbol타입을 만들어낼 수 있다. (함수는 대문자S, 타입은 소문자s)
console.log(Symbol('foo') === Symbol('foo'));
// 같은 함수, 같은 인자지만 결과는 다름
  • primitive 타입의 값을 담아서 사용한다.
  • 고유하고 수정불가능한 값으로 만들어준다.
  • 접근을 제어하는데 주로 쓰인다.
const sym = Symbol(); // sym은 고유한 형태
const obj = {
	[sym]: "value"
}
console.log(obj[sym]); // "value"

 

4. Null & undefined

  • 그 자체로 유용하지 않고, 소문자만 존재한다.
  • number(와 같은 다른 타입)에는 null또는 undefined를 할당 가능
  • --stricNullChecks 컴파일 옵션 사용 시 nullundefined는 자기 자식 혹은 void(undefined에 할당)만 할당 허용
  • 이때, nullundefined를 할당 가능하게 하려면 union type | 을 이용할 수 있다.
let v: void = undefined; // 타입인 동시에 값인 undefined, void는 값만 넣을 수 있고 자기 자신도 넣을 수 없다.

let union: string = null; // error!
let union: string | null = null; // null할당 가능

4-1. JavaScript에서의 null

  • null이란 값으로 할당된 것이 null이다. 
  • null이라는 타입은 null이라는 값만 가질 수 있다.
  • 무언가 있지만 사용할 준비가 덜 된 상태
  • 런타임에서 typeof연산자를 사용할 경우 -> object
let n: null = null; // null타입은 null
console.log(n); // 값 null
console.log(typeof n); // object

4-2. JavaScript에서의 undefined

  • 값이 할당하지 않은 변수는 undefined라는 값을 가진다.
  • object의 property가 할당되지 않았을 때도 undefined라는 값을 가진다.
  • 무언가 아예 준비가 안 된 상태
  • 런타임에서 typeof연산자를 사용할 경우 -> undefined
let u: undefiend = undefiend; // undefiend타입은 undefiend
console.log(u); // 값 undefiend
console.log(typeof u); // undefiend

 

 

5. Object

const person1 = { name: "siot", age: 99 };

내장 전역 객체 Object를 이용해 create메소드를 통해 객체 생성 -> 어떤 인자가 들어가야 할까
const person2 = Object.create({ name: "siot", age: 99 });
  • primitive type이 아닌 것을 나타내고 싶을 때 사용하는 타입
  • 다음과 같은 방식으로 type annotation하지 않는다.
let obj: object = {};
  • 표현방법
obj = {name: 'siot'};
obj = [{name: 'siot'}];
  • non-primitive type : error를 부르는 형식
obj = 99; //error
obj = 'siot'; //error
obj = true; //error //error
obj = 100n; //error, bigint 타입
obj = Symbole(); //error
obj = null; //error
obj = undefined; //error
declare function create(o: object | null): void;
create({prop: 0});
create(null);
create(42); // Error
create("string"); // Error
create(false); // Error
create(undefined); // Error
object.create(0); // Error

 

 

6. Array

6-1. Javascript에서 array는 객체다.

6-2. 표현방법 (공통의 타입으로 묶일 때)

      ㄴ 선호되는 방식 number[]

let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];

6-3. 표현방법 (여러 타입으로 배열할 때)

let list: (number | string)[] = [1, 2, 3, "4"]

 

 

7. Tuple

  • 순서와 타입, 길이도 일치해야 함
let x: [string, number];
x = ["hello", 99];
x[3] = "world"; // undefiend

const [first, second, third] = person;

 

 

8. Any

  • undefined지만 타입에 구애받지않고 “어떤 것이든” 올 수 있음
  • 최대한 쓰지 않는게 안전하나 쓸 수밖에 없는 상황도 있음
  • 컴파일 타임에 타입 체크가 정상적으로 이뤄지지 않으므로 지양
function returnAny(message): any {
	console.log(message);
}

const any1 = returnAny("리턴");

*any타입을 작성하지 않을 시 에러를 잡아주는 strict의 옵션 nolmplicitAny

  • 개체를 통해 전파된다.
let looselyTyped: any = {};
const d = looselyTyped.a.b.c;

 

 

9. Unknown

  • 응용 프로그램을 작성할 때 모르는 변수의 타입을 묘사할 때
  • 동적 콘텐츠, 사용자나 API의 모든 값을 의도적으로 수락하기를 원할 때
  • 이 변수가 무엇이든 될 수 있음을 알려주는 타입을 제공할 때
  • any보다 이후에 typescript 3.0버전부터 지원
  • any와 짝으로 any보다 type-safe한 타입
  • any와 같이 아무거나 할당할 수 있다.
  • 컴파일러가 타입을 추론할 수 있게 타입의 유형을 좁힌다.
  • 타입을 확정해주지 않으면 다른 곳에 할당할 수 없고 사용할 수 없다.
  • unknown타입을 사용하면 런타임 에러를 줄일 수 있다.
  • 사용 전에 데이터의 일부 유형 검사를 수행해야 함을 알리는 API에 사용
declare const maybe: unknown;


const aNumber: number = maybe;

if (maybe === true) {
	const aBoolean: boolean = maybe;
} // if문 안에서 한정되어 타입 가드

if (typeof maybe === 'string') {
	const astring; string = maybe;
} // if문 안에서 한정되어 타입 가드

 

 

10. Never

  • 모든 타입의 subtype으로 모든 타입에 할당 가능 하지만 어떤 것도 할당 할 수 없음
  • anynever에게 할당할 수 없음
  • Return에 사용되는 타입
function error(message: string): never {
	throw new Error(message); // 리턴하지 않음 
}

function fail() {
	return error("failed");
}

function infiniteLoop(): never {
	while(true) {}
}
  • 모든 타입의 subtype이며 모든 타입에 할당 가능 반대로 never에는 어떤 것도 할당 불가
  • anynever에 할당 불가
  • 잘못된 타입을 넣는 실수를 막고자 할 때 사용하기도 함
let a: string = "hello";
if (typeof a !== 'string') {
	a; // never
}


declare cosnt a: string | number;
if (typeof a !== 'string') {
	a; // number, typeof가드
}

 

 

11. void

  • 어떤 타입을 가리키지 않는 빈 상태
  • 변수에 void를 지정하지 않고 값을 반환하지 않는 undefined를 반환하는 상태에 return타입으로 사용
  • 아무것도 하지 않겠다는 것을 명시적으로 하는 타입
function returnVoid(message: string): void{
	console.log(message);
    return undefined;
}
728x90
728x90

1. First Type Annotation

특정 변수나 객체 등에 type을 지정하는 것

1-1.

 const a: string = "Lenord" 

1-2.

function hello(b: number) {}

hello(30);

 

 

2. TypeScript에서 프로그램 작성을 위해 기본 제공하는 데이터 타입

ECMAScript 표준에 따른 기본 자료형 6가지 포함(Superset) + TypeScript 데이터타입

Boolean / Number / String / Null / Undefined / Symbol / Array(Object형) +

Any / Void / Never / Unknow / Enum / Tupe(Object형)

 

 

3. Primitive Type

3-1. Object와 레퍼런스 형태가 아닌 실제 값을 저장하는 자료형

3-2. Primitive 형의 내장 함수를 사용 가능한 것은 자바스크립트 처리 방식 덕분

     ㄴ Boolean / Number / String / Null / Undefined / Symbol

3-3. literal 값(값 자체를 문자로 할당하는 방식)으로 primitive타입의 서브 타입을 나타낼 수 있다.

true; // 불린의 서브 타입
'hello'; // 문자열의 서브 타입
3.14; // 넘버의 서브 타입
null;

3-4. 래퍼 객체로 만들 수 있다. (TypeScript에서는 권장하지 않음)

new Boolean(false); // typeof new Boolean(false) : 'object'
new String('world'); // typeof new String('world') : 'object'
new Number(42); // typeof new Number(42) : 'object'

3-5. TypeScript의 Type Casing

TypeScript은 primitive types 모두 소문자로 작성하는 것을 권장함

728x90
728x90

Typed Superset of JavaScript

  • TypeScript는 타입을 추가해 JS를 확장하는 언어다.
  • 코드를 실행하기 전에 컴파일하는 시점에서 에러를 잡거나 고치는 데 시간을 줄일 수 있다.
  • 어떤 브라우저나 운영체제, JS 런타임 환경에서도 가능한 완전한 오픈 소스다.
  • 에디터로 작성된 TS는 Compiler(transpile)과정을 통해 TS코드를 JS코드로 변경해 브라우저나 노드js환경에서 실행가능하도록 한다.

 

 

1. 자바스크립트 실행 환경

1-1. node.js : 크롬 V9 JS 엔진을 사용하여 서버사이드에서도 실행하도록 런타임 환경을 제공

1-2. browser : html을 동적으로 만들기 위해 브라우저에서 js를 해석하고 DOM을 제어할 수 있도록 하는 자바스크립트 런타임 환경

 

 

 

2. node.js 설치 (nvm과 npm)

 

Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

2-1. LTS버전 VS Current최신 버전 차이점

      ㄴ LTS는 검증되고 안정적인 버전

 

2-2. node.js version manager

nvm : node.js 버전을 관리하는 매니저

 

nodejs 운영체제별 다운로드 및 노드 버전 매니저 nvm

1. 노드 버전 매니저 1-1. MacOS 📍nvm 검색 📍Installing and Updation  ㄴ 설치 & 업데이트 스크립트에서 curl로 시작하는 부분 복사해서 터미널에 입력  ㄴ nvm --version : 버전 확인 1-2. WindowOS 📍nvm-..

siot0.tistory.com

 

2-3. npm 자동 설치

 ㄴ 외부 패키지를 설치할 수 있게 하는 관리자 프로그램

 

 

 

컴파일러는 TS를 JS로 변환해주는 역할

3. TypeScript 컴파일러 설치 cli 

*cli : Command Line Interface 명령 줄 인터페이스

$ npm i typescript -g

$ node_modules/.bin/tsc
$ tsc source.ts // 컴파일러 실행 + 파일

 

📍 3-1. 타입스크립트 컴파일러 글로벌로 설치

$ npm i typescript -g // 전역 설치
$ tsc 특정파일이름 // 컴파일러 명령어
$ tsc --init // tsconfig.json 생성
$ tsc -w

-w : tsc 명령어를 매번 실행하지 않더라도 tsc -w (watch)모드는 자동으로 컴파일됨

 

 

📍 3-2. 프로젝트에만 타입스크립트 컴파일러 설치 (해당 프로젝트에만 -D)

$ npm init -y  // package.json 생성
$ npm i typescript -D // package.json에 typescript 추가됨
$ npx tsc --init // tsconfig.json 생성
$ npx tsc -w

node_modules/.bin/tsc는 node_modules/typescript/bin/tsc와 연결됨

컴파일을 실행할 때 이 경로를 작성해야 하는데 너무 길기 때문에 사용할 수 있는 명령어 npx

 

$ nano test.ts // 새 파일 생성 명령어

$ mkdir tsc-folder // 새 폴더 생성 명령어

$ npm uninstall typescript -g // 전역 삭제

 

 

📍 3-3. VSCODE는 컴파일러가 내장됨 (번들)

$ npm init -y
$ npm i typescript -D

하단 파란 바에서 typescript 버전(숫자)을 클릭 > Select TypeScript Version  > 버전 선택 가능 

 

 

 

👩‍💻 npm과 npx의 차이점

npm은 node.js를 설치하면 자동으로 설치되는 패키지 관리 프로그램으로 전역 혹은 로컬 둘다 설치할 수 있다. (3-1, 3-2)

특정 패키지를 찾거나 어떤 명령어를 사용할 때는 종종 로컬 node_modues 폴더에 dependencies(-D)로 설치해야만 하는 경우가 생길 때가 있다. 이때 npx에 넣을 수 있다. npm 레지스트리 안에서 호스트된 개발용의존성을 쉽게 설치하고 관리하는 것이 목표다. 즉, 로컬에 설치된 패키지를 실행하고 싶다면, 아래처럼 입력하면 끝

$ npx your-package

 

728x90
728x90

🌲 정규식 Regular Expression

 

문자열을 검색하고 대체하는 데 사용 가능한 일종의 형식 언어(패턴)

간단한 문자 검색부터 이메일, 패스워드 검사 등 복잡한 문자 일치 기능 등

 

🚨 정규표현식 정리

 

GitHub - kim-siot/regexp_test

Contribute to kim-siot/regexp_test development by creating an account on GitHub.

github.com

 

 

 


 

🚨 자바스크립트 정규식 생성 방식

1) 생성자 함수 방식

new RegExp('표현', '옵션')

new RegExp('[a-z]', 'gi')

2) 리터럴 방식

/표현/옵션

/[a-z]/gi

3) 정규식 표현으로 'a'찾기

const str = `
010-1234-5678
siot@email.com
http://www.omdbapi.com/?apikey=7035c60c&s=frozen
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
abbcccddd
`

const regexp = new RegExp('a', 'g') // 생성자 함수 방식
const regexp = /a/g // 리터럴 방식
console.log(str.match(regexp))

 

 

 


 

🚨 자바스크립트 메소드

💻 test()

정규식과 일치하는 특정 문자가 있는지 불린 데이터로 반환

정규식.test(문자열)

const regexp = /Ipsumd/gi
console.log(regexp.test(str)) // true

 

💻 match()

일치하는 문자열의 배열 데이터를 반환

문자열.match(정규식)

 

💻 replace()

일치하는 문자열을 대체하고 대체된 문자열을 반환

문자열.replace(정규식, 대체문자)

const regexp = /bb/gi
console.log(str.replace(regexp, 'BB'))

 

 


🚨 플래그 (옵션)

 

\.$

. (온점) : 임의의 한 문자와 일치시키는 명령이기 때문에 문자.(온점)을 찾기 위해서는 앞에 \백슬래쉬를 붙여 이스케이프 문자로 바꿔준다.

*Escape Character (이스케이프 문자) : \ 백슬래시 기호를 통해 본래의 기능에서 벗어나 상태가 바뀌는 문자

console.log(str.match(/h..p/g))

 

$ : 끝부분에 일치

str.match(/\.$/g)

 

m : 문자데이터는 하나의 시작점과 끝점이 존재하는데 m 플래그를 사용하면 줄바꿈 했을 때 각각의 줄에 또다른 시작점과 끝점을 만들어낸다고 이해

str.match(/\.$/gm)

 

 


🚨 패턴 (표현)

 

63개의 문자와 일치하지 않는 경계 + f로 시작하는 단어 찾기

str.match(/\bf\w{1,}/g)

 

숫자 찾기

str.match(/\d{1,]/g)

 

모든 공백을 찾아 제거

str.replace(/\s/g, '')

 

특정 문자 뒤에서 일치하는 문자 찾기 (?<=)

ㄴ @문자 뒤로 1개 이상 일치하는 임의의 문자 찾기

str.match(/(?<=@).{1,}/g)

 

a|b : a또는 b와 일치, 이때 플래그g를 작성하지 않으면 첫번째 패턴만 찾음

str.match(/the|text/g)

 

ab? : b가 없거나 b와 일치

str.match(/https?/g) // ["http", "https"]
728x90
728x90

 

🌲 Open Movie Database API

 

OMDb API - The Open Movie Database

 

www.omdbapi.com

 

 

🚨 주소 사용법

*yourkey : 사용자키 필요. 무료 발급

*Parameter: 명령 / Required : 필수

 

 

🚨 주소 구조 (쿼리스트링)

 

🚨 예시 : frozen검색하기

s=frozen

http://www.omdbapi.com/?apikey=7035c60c&s=frozen

주소창에서 바로 실행하면 아래와 같이 JSON포맷으로 출력됨

{"Search":[{"Title":"Frozen","Year":"2013","imdbID":"tt2294629","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMTQ1MjQwMTE5OF5BMl5BanBnXkFtZTgwNjk3MTcyMDE@._V1_SX300.jpg"},{"Title":"Frozen II","Year":"2019","imdbID":"tt4520988","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMjA0YjYyZGMtN2U0Ni00YmY4LWJkZTItYTMyMjY3NGYyMTJkXkEyXkFqcGdeQXVyNDg4NjY5OTQ@._V1_SX300.jpg"},{"Title":"Frozen","Year":"2010","imdbID":"tt1323045","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMTc5MTg0ODgxMF5BMl5BanBnXkFtZTcwODEzOTYwMw@@._V1_SX300.jpg"},{"Title":"The Frozen Ground","Year":"2013","imdbID":"tt2005374","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BYzM3Mjc1ZDItMTE1OC00ODk0LWFmZjctYzgxZmYwNzliMTdkXkEyXkFqcGdeQXVyMTAxNDE3MTE5._V1_SX300.jpg"},{"Title":"Frozen Planet","Year":"2011–2012","imdbID":"tt2092588","Type":"series","Poster":"https://m.media-amazon.com/images/M/MV5BOGM5YWU2N2QtYjVhZi00MzYyLTk0ODctYmVlNDZlMjU5N2Q5XkEyXkFqcGdeQXVyMzU3MTc5OTE@._V1_SX300.jpg"},{"Title":"Frozen River","Year":"2008","imdbID":"tt0978759","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMTk2NjMwMDgzNF5BMl5BanBnXkFtZTcwMDY0NDY3MQ@@._V1_SX300.jpg"},{"Title":"Frozen Fever","Year":"2015","imdbID":"tt4007502","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BMjY3YTk5MjUtODBjOC00NzAwLTgyYjYtMzFmMzAxOTZmOWRlXkEyXkFqcGdeQXVyNDgyODgxNjE@._V1_SX300.jpg"},{"Title":"Olaf's Frozen Adventure","Year":"2017","imdbID":"tt5452780","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BOWQ1NjNiZTEtYzc3Zi00Nzk4LTg5MTYtNzc5NmJjYTg1MGQ4XkEyXkFqcGdeQXVyMTA4NDI1NTQx._V1_SX300.jpg"},{"Title":"Warcraft III: The Frozen Throne","Year":"2003","imdbID":"tt0372023","Type":"game","Poster":"https://m.media-amazon.com/images/M/MV5BNTMwOGQzYjMtYTQ5MS00NjNmLTk4OTktMDljZDYzNjgwMjUzXkEyXkFqcGdeQXVyNjExODE1MDc@._V1_SX300.jpg"},{"Title":"Howard Lovecraft and the Frozen Kingdom","Year":"2016","imdbID":"tt4768656","Type":"movie","Poster":"https://m.media-amazon.com/images/M/MV5BNTAyYTAzMTktZTNkNC00NDI3LTllMTgtMmU4NDFlMzc0NTkyXkEyXkFqcGdeQXVyNDUxMzY1Mw@@._V1_SX300.jpg"}],"totalResults":"300","Response":"True"}

 

 

 

 


🌲 OMDb API 서버에 영화정보 요청&응답&처리

 

🚨 axios 패키지

Promise based HTTP client for the browser and node.js

: 브라우저와 nodejs환경에서 사용할 수 있는 (js에서 사용되는) promise객체 기반의 HTTP 요청을 처리해주는 js 패키지

 

GitHub - axios/axios: Promise based HTTP client for the browser and node.js

Promise based HTTP client for the browser and node.js - GitHub - axios/axios: Promise based HTTP client for the browser and node.js

github.com

📍 axios 패키지 설치

$ npm install axios

📍 axios 패키지 import

import axios from 'axios'

 

 

🚨 frozen검색어 요청

axios.get().then 메소드 체이닝형식

ㄴ 요청하면 응답을 axios 패키지가 내부적으로 처리하여 then메소드에 콜백에서 처리하는 로직

*요청할 때는 https로

import axios from 'axios'

function fetchMovies () {
  axios
    .get('https://www.omdbapi.com/?apikey=7035c60c&s=frozen')
    .then(res => {	// 화살표 콜백함수
      console.log(res)
    })
}

fetchMovies()

 

 

🚨  html에 타이틀과 포스터 이미지 가져오기

<h1></h1>
<img src="" alt="" width="200">
import axios from 'axios'

function fetchMovies () {
  axios
    .get('https://www.omdbapi.com/?apikey=7035c60c&s=frozen')
    .then(res => {
      console.log(res)
      const h1El = document.querySelector('h1')
      const imgEl = document.querySelector('img')
      h1El.textContent = res.data.Search[0].Title
      imgEl.src = res.data.Search[0].Poster
    })
}

fetchMovies()

728x90
+ Recent posts
728x90